;       SCCSID = @(#)d_chgfp.asm	6.1 91/02/15
;	SCCSID = @(#)d_chgfp.asm	1.4 90/01/22
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
;***  d_chgfp.asm - API stub routine DosChgFilePtr
;
;	Member of API library
;	Steve Salisbury & Bill Mershon
;	Copyright MicroSoft Corporation, 1986
;	18-Feb-1986
;
;	library routine for API simulator
;
;	Called from dos 2.x,3.x compatible dos 5.x applications
;
;	Special Information
;		none
;
;	Modification History
;
;	5-Aug-86 (davidsi): Added checking for negative offsets
;	beyond the beginning of file.
;
;	9-Sep-86 (billme): added check; if character device, then
;	return error code ERROR_SEEK_ON_DEVICE
;
;	24-Sep-86 (billme): add check for error after IOCTL
;
;	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-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.
;
;	17-June-87 (stevee): fix to insure that all file handles in FAPI
;	are less than MAX_HANDLES (p5553)
;
;*****************************************************************

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

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

;***	DOSCHGFILEPTR - stub to emulate DOSCHGFILEPTR function call
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;	errorcode = unsigned far pascal
;	DosChgFilePtr (FileHandle, Distance, MoveType, NewPointer)
;
;	ENTRY:
;		FileHandle - file handle
;		Distance - distance to move in bytes
;		MoveType - method of moving
;		NewPointer - new pointer location
;
;	RETURN:
;		AX = 0 if no error, else error code (see DOS 5 spec)
;
;	EXIT:
;		NewPointer contains the new pointer
;
;	USES:
;		AX
;
;	Pseudo Code:
;		save registers
;		use BP as pointer to stack parameters
;		If the offset is negative, check if within bounds of file.
;		load registers for int 21 call
;		execute int 21 with function 42h
;		restore registers
;		return
;
;	WARNING:
;		may return error code from Dos 2.x, 3.x (see dos manuals)
;
;	EFFECTS:
;		none
;

	title	DOSCHGFILEPTR - stub to emulate DOSCHGFILEPTR function call
;
;	EXTRN	DOSCHGFILEPTR:FAR
;
;	PUSH	WORD FileHandle
;	PUSH	DWORD Distance
;	PUSH	BYTE MoveType
;	PUSH	@ DWORD NewPointer
;	CALL	DOSCHGFILEPTR
;

DEVICE_FLAG	EQU	080h


_TEXT	segment byte public 'CODE'

	assume	CS:_TEXT,DS:NOTHING

	extrn __api_dev_table : word

	public	DOSCHGFILEPTR

FileHandle	equ	[BP+16] ; WORD
Distance	equ	[BP+12] ; DWORD
MoveType	equ	[BP+10] ; WORD
NewPointer	equ	[BP+6]	; @ DWORD

DOSCHGFILEPTR	proc	far

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

	mov	bx,FileHandle			; BX <- handle
	cmp	bx,MAX_HANDLES			; real mode < 20 handles
	jb	chfp0				; handle is valid
	mov	ax,ERROR_INVALID_HANDLE		; handle is invalid
	jmp	short NormalExit		; quit

chfp0:
	.erre	D2_IOCTL LT 256
	mov	ax,D2_IOCTL SHL 8		; AL <- 0
	int	21h				; if IOCTL fails
	jc	ErrorExit			; then return error
	test	dx,DEVICE_FLAG			; if handle refers to device
	mov	ax,ERROR_SEEK_ON_DEVICE
	jnz	NormalExit			; then return error

	mov	si,word ptr Distance+2		; SI:DI <- distance to move
	mov	di,word ptr Distance

	test	si,si				; if offset is positive
	jns	chfp1				; then just execute move
	xor	cx,cx				; zero offset
	xor	dx,dx
	mov	ax,MoveType
	mov	ah,D2_MoveFilePtr		; DX:AX <- current position
	int	21h				; if error getting position
	jc	ErrorExit			; then return error

	; Are we attempting to seek past the beginning of the file?

	add	ax,di
	adc	dx,si
	mov	ax,ERROR_NEGATIVE_SEEK
	js	NormalExit		;@@ added support for DOSErrorClass

chfp1:
	mov	cx,si				; CX:DX <- distance to move
	mov	dx,di
	mov	ax,MoveType			; AL <- move type
	mov	ah,D2_MoveFilePtr
	int	21H
	jc	ErrorExit

	lds	bx,NewPointer		; store new pointer
	mov	DS:[bx],ax
	mov	DS:[bx+2],dx
	xor	ax,ax
	jmp	NormalExit		;@@ Added support for DOSErrorClass
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	12	; clear stack of entry parameters (bytes)
DOSCHGFILEPTR	endp

_TEXT	ends

	end
