;       SCCSID = @(#)d_flock.asm	6.1 91/02/15
;	SCCSID = @(#)d_flock.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_flock.asm - API stub routine DosFileLocks
;
;	Member of API library
;	Bill Mershon
;	Copyright MicroSoft Corporation, 1986
;	13-May-1986
;
;	library routine for API simulator
;
;	Called from dos 2.x,3.x compatible dos 5.x applications
;
;	Special Information
;		none
;
;	Modification History
;
;	2-Dec-86 (billme): convert to latest spec in response
;	to (version 1.1) ptm 164 and clean up a bit
;
;	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.
;
;	10-June-87 (Tarng): 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 FAPI file handles are
;	less than MAX_HANDLES (p5553)
;

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

	EXTRN	__api_begin:near
	EXTRN	__api_end:near
	EXTRN	_api_getvrsn:near
	EXTRN	api_get_extended:far	;@@


;***	DOSFILELOCKS - stub to emulate DOSFILELOCKS function call
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;	errorcode = unsigned far pascal
;	DosFileLocks(FileHandle, ptr_UnLockList, ptr_RangeLockList)
;
;	ENTRY:
;		FileHandle - handle of target file
;		ptr_UnLockList - pointer to list of ranges to unlock
;		ptr_RangeLockList - pointer to list of ranges to lock
;
;	RETURN:
;		AX = 0 if no error, else error code (see DOS 5 spec)
;
;	EXIT:
;
;	USES:
;		AX
;
;	WARNING:
;		may return error code from Dos 2.x, 3.x (see dos manuals)
;		user should trap int 23 and 24 (see dos 3.x manual)
;
;	EFFECTS:
;		none
;

	title	DOSFILELOCKS - stub to emulate DOSFILELOCKS function call
;
;	EXTRN	DOSFILELOCKS:FAR
;
;	PUSH	WORD FileHandle
;	PUSH	@ OTHER UnLockList
;	PUSH	@ OTHER LockRangeList
;	CALL	DOSFILELOCKS
;

_TEXT	segment byte public 'CODE'

	assume	CS:_TEXT,DS:NOTHING

	public	DOSFILELOCKS

LOCK_OP		equ	0	; for DOS 3.x call (see dos 3.x manual)
UNLOCK_OP	equ	1

FileHandle		equ	[BP+14]
ptr_UnLockList		equ	[BP+10]
ptr_LockRangeList	equ	[BP+6]

DOSFILELOCKS	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	flock0				; handle is valid
	mov	ax,ERROR_INVALID_HANDLE		; handle is invalid
	jmp	short NormalExit		; quit

flock0:
	call	_api_getvrsn		; AX <- version
	cmp	ah,3			; if major version < 3
	mov	ax,0			; (set noerror in case of return)
	jb	NormalExit		; then return no error

	lds	bx,ptr_UnLockList	; DS:BX <- pointer to UNLOCK list
	mov	cl,UNLOCK_OP
	call	dolock			; if DOS error from dolock
	jc	ErrorExit		; then return error

	lds	bx,ptr_LockRangeList	; DS:BX <- pointer to LOCK list
	mov	cl,LOCK_OP
	call	dolock			; if DOS error from dolock
	jc	ErrorExit		; then return error

	xor	ax,ax
	jmp	short NormalExit	;@@ Added support for DOSErrorClass
ErrorExit:				;@@
	call	api_get_extended	;@@
NormalExit:				;@@

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

	ret	10	; clear stack of entry parameters (bytes)
DOSFILELOCKS	endp

_TEXT	ends


;***	dolock - local routine to perform locking
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;	call dolock
;
;	ENTRY:
;		DS:BX is pointer to locking/unlocking list
;		CL operation (0 for lock, 1 for unlock)
;
;	RETURN:
;		AX = 0 if no error, else error code (see DOS 5 spec)
;
;	EXIT:
;
;	USES:
;		AX
;
;	WARNING:
;		may return error code from Dos 2.x, 3.x (see dos manuals)
;
;	EFFECTS:
;		none
;

;
;	CALL	dolock
;

_TEXT	segment byte public 'CODE'

	assume	CS:_TEXT,DS:NOTHING

dolock	proc	near

	mov	ax,ds
	or	ax,bx			; if pointer is null
	jz	lock_exit		; then return (note: OR clears carry)
	mov	al,cl			; AL <- operation (lock or unlock)
	mov	dx,ds:[bx]		; DX <- offset low
	mov	cx,ds:[bx+2]		; CX <- offset high
	mov	di,ds:[bx+4]		; DI <- length low
	mov	si,ds:[bx+6]		; SI <- length high
	mov	bx,FileHandle
	mov	ah,D2_LockUnlockFile
	int	21h			; if DOS error
lock_exit:
	ret

dolock	endp

_TEXT	ends


	end
