;       SCCSID = @(#)d_news.asm	6.1 91/02/15
;      SCCSID = @(#)d_news.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_NEWS.ASM - API stub routine DosNewSize
;
;	Member of API library
;	David Silverstein
;	Copyright MicroSoft Corporation, 1986
;	26-Jun-1986
;
;	library routine for API simulator
;
;	Called from dos 2.x,3.x compatible dos 5.x applications
;
;	Special Information
;		none
;
;	Modification History
;
;	11-Nov-86 (billme): correct problem detailed by ptm 3713
;	by removing corruption of AX and adding location dns00
;
;	15-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-May-87 (robertc): Install hooks for DOSErrorClass Support.
;	All int 21h errors are passed through api_get_extended to get the
;	extended errorcode and to provide the class, action, and locus for
;	the dynamic error FIFO queue.
;
; @@	18-May-87 (giacomoa): Fix bug in exit routine, when new size was
; @@	successfully set, skip call to api_get_extended (which trashed AX)
;
; @@	11-June-87 (Tarng): Fix bug for ptm 5469.
;
;	17-June-87 (stevee): fix to insure that all FAPI file handles are
;	less than MAX_HANDLES (p5553)
;
; @@	9-July-87 (Tarng): Fix bug for ptm 6060 setup handle before calling
;	int 21h.
;
;	8-18-87 (robertc): test to assure handle is attached to a filep7047
;
;	8-24-87 (robertc): fix bug introduced by ptm7047
;
;	10-26-87 (robertc): change error for device from disk full to
;	invalid handle.
;
;	11-23-87 (marieu): correction to logic which compares old file size
;	with new file size ptm1317

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

	EXTRN	api_get_extended:far	;@@ added support for DOSErrorClass
	EXTRN	__api_begin_lsf:near
	EXTRN	__api_end:near
	EXTRN	__api_devtab_ptr:near

;***	DOSNEWSIZE
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;	errorcode = unsigned far pascal
;	DosNewSize(FileHandle, FileSize)
;
;	ENTRY:
;		FileHandle - File Handle of file to change
;		FileSize - New file size
;
;	RETURN:
;		AX = 0 if no error, else error code (see DOS 5 spec)
;
;	Pseudo Code:
;		save registers
;		use BP as pointer to stack parameter
;		Get and save current file pointer
;		Seek to end of file to get file size
;		If new file size is positive
;			seek to new file size - 1
;			write one byte
;			if write failed, report ERROR_DISK_FULL
;		If new file size is negative
;			seek to new file size position
;			write zero bytes (to truncate)
;		restore file pointer
;		restore registers
;		return
;
;	WARNING:
;		may return error code from Dos 2.x, 3.x (see dos manuals)
;

	title	DOSNEWSIZE
;
;	EXTRN	DOSNEWSIZE:FAR
;
;	PUSH	WORD FileHandle
;	PUSH	DWORD FileSize
;	CALL	DOSNEWSIZE
;

FROM_BEG_OF_FILE	equ	0		; lseek from beg of file
FROM_CURRENT_FILE_PTR	equ	1		; lseek from current file ptr
FROM_END_OF_FILE	equ	2		; lseek from end of file

TRUNCATE_FILE		equ	0
EXTEND_FILE		equ	1


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

	public	DOSNEWSIZE

FileHandle	equ	[bp + 10]
FileSize	equ	[bp + 6]
CurFilePointer	equ	[bp - 4]		; local save of current fp
testdev_mask	equ	0f0h

DOSNEWSIZE	proc	far
IFDEF api_debug_pause
	int	3	; included ONLY IF api_debug_pause is defined
ENDIF

	mov	ax,4
	call	__api_begin_lsf ; init bp and save bp,ds,bx,cx,dx,si,di,es
				; also create local stack frame (size of ax)
				; required to save: bp,bx,cx,dx,ds

	mov	bx, [FileHandle]
	cmp	bx,MAX_HANDLES	; is handle > max allowed in real mode?
	jb	tstdev		; no
	mov	ax,ERROR_INVALID_HANDLE ; return error if handle invalid
	jmp	NormalExit	; quit

tstdev:
	mov	ax,[FileHandle] 		;@@PTM 7047
	call	__api_devtab_ptr		;@@ check the device table
	mov	ax,error_invalid_handle 	;@@ prepare error
	test	cs:[bx].hi_attrdev,testdev_mask ;@@ tis it a device
	jz	dns000				;@@
	jmp	NormalExit

dns000:
	mov	bx, [FileHandle]		; @@

	xor	cx, cx				; get current file position
	mov	dx, cx
	mov	ah, D2_MoveFilePtr		; get file pointer
	mov	al, FROM_CURRENT_FILE_PTR
	int	21h
	jc	ErrorExit		;@@ added support for DOSErrorClass
	mov	[CurFilePointer], ax		; save current file pointer
	mov	[CurFilePointer + 2], dx

	mov	dx, cx				; move to eof to get file size
	mov	ah, D2_MoveFilePtr
	mov	al, FROM_END_OF_FILE
	int	21h
	jc	ErrorExit		;@@ added support for DOSErrorClass
	mov	cx, word ptr [FileSize + 2]	; get high word of file size
	test	cx, cx				; if new file size not negative
	jns	dns00				; then continue
	mov	ax, error_invalid_parameter	; else exit with error
	jmp	short NormalExit
dns00:
	cmp	cx, dx				; is new file size larger?
	mov	dx, word ptr [FileSize]
	ja	dns0				; go extend file
	jb	smaller 			; @@ check for smaller
	cmp	dx, ax
	ja	dns0				; go extend file
						; @@ continue here if smaller
smaller:					; stand still and write nothing
						; stand still and write nothing
	mov	ah, D2_MoveFilePtr		; prepare to move file pointer
	mov	al, FROM_BEG_OF_FILE		; to new eof
	int	21h
	jc	ErrorExit		;@@ added support for DOSErrorClass
	mov	ah, D2_WriteForD
	xor	cx, cx				; truncate file
	int	21h
	jc	dns4
	jmp	short dns3
dns0:						; backup one and write one
	mov	ah, D2_MoveFilePtr		; prepare to move file pointer
	mov	al, FROM_BEG_OF_FILE		; to new eof

	sub	dx,1				; decrement low word pointer
	jnc	dns1				; if dx wraps
	dec	cx				; then decrement high word
dns1:
	int	21h				; seek to one before new end
	jc	ErrorExit		;@@ added support for DOSErrorClass
	mov	ah, D2_WriteForD		; file is being extended
	mov	cx, 1				; write one (random) byte
	int	21h
	jc	dns4
	cmp	ax, 1				; if byte was NOT written OK
	mov	ax, ERROR_DISK_FULL
	jne	short dns5			; @@ skip get extended error

dns3:
	xor	ax, ax				; clear error code
	jmp	short dns5			; @@ skip get extended error
dns4:
	call	api_get_extended	;@@ added support for DOSErrorClass
dns5:
	push	ax				; save error return code
	mov	cx, [CurFilePointer + 2]	; restore file pointer
	mov	dx, [CurFilePointer]
	mov	ah, D2_MoveFilePtr
	mov	al, FROM_BEG_OF_FILE
	mov	bx, [FileHandle]		;@@ ptm 6060
	int	21h
	jc	dns51				;@@
	pop	ax				; restore error return code
	jmp	short NormalExit	;@@ Added support for DOSErrorClass
dns51:					;@@
	add	sp,2			;@@ discard ax

ErrorExit:				;@@ added support for DOSErrorClass
	call	api_get_extended	;@@ added support for DOSErrorClass
NormalExit:				;@@ added support for DOSErrorClass

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

	ret	6
DOSNEWSIZE	endp

_TEXT	ends

	end
