⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 redir.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 4 页
字号:
	mov	ss:dma_offset,dx	; save for xfer
	mov	ss:dma_segment,di
	call	int2f_dhndl		; try the xfer
	pop	ss:dma_segment
	pop	ss:dma_offset
	mov	bx,0			; assume no error
	 jnc	redir_rw20
	xchg	ax,bx			; return error code
	cmp	bx,ED_LOCKFAIL		; is it a lockfail error ?
	 jne	redir_rw20		; no, just return it
	les	di,ss:current_dhndl	; compatibility modes should generate
	test	es:DHNDL_MODE[di],DHM_SHAREMSK
	 jz	redir_rw20		;  critical errors fro ED_LOCKFAIL
	mov	bx,ED_ACCESS		; sharing modes return access denied
redir_rw20:
	ret
	

eject
;	DELETE FILE (UNLINK)

;	+----+----+----+----+----+----+
;	|    41   |        name       |
;	+----+----+----+----+----+----+

;	entry:
;	------
;	name:	segmented address of ASCIIZ name

;	exit:
;	-----
;	BX:	0000 or error code ( < 0)


redir_unlink:
	mov	ax,I2F_DEL		; it's a delete
;	mov	file_attrib,6		; only delete files
redir_unlink_move_common:
	push	ax
	call	get_attrib_mode		; allow overrides for server calls
	pop	ax
	jmp	redir_pathop_common

eject
;	GET/SET FILE POSITION (LSEEK)

;	+----+----+----+----+----+----+----+----+----+----+
;	|    42   |  handle |       offset      |  method |
;	+----+----+----+----+----+----+----+----+----+----+

; On Entry:
;	ES:BX = DHDNL_
;	method:	0 = begin, 1 = current, 2 = end of file
;
; On Exit:
;	BX = Error Code, offset updated with new value
;

redir_lseek:
;-----------
	mov	di,bx			; ES:DI -> DHNDL_
	mov	si,2[bp]		; SI -> parameter block
	mov	dx,4[si]		; get 32-bit file offset
	mov	cx,6[si]		; into CX,DX
	mov	ax,8[si]		; get seek mode
	test	ax,ax
	 jz	redir_lseek20		; seek from beginning
	dec	ax
	 jz	redir_lseek10		; seek from current position
	dec	ax
	 jz	redir_lseek30		; seek from end
	mov	bx,ED_DATA		; else invalid seek mode
	ret

redir_lseek10:				; seek mode 1: relative to position
	add	dx,es:DHNDL_POSLO[di]	; add position + offset
	adc	cx,es:DHNDL_POSHI[di]
;	jmps	redir_lseek20

redir_lseek20:				; seek mode 0: set absolute position
	mov	es:DHNDL_POSLO[di],dx	; set new file offset
	mov	es:DHNDL_POSHI[di],cx	; SI = error code/0 at this point
;	jmps	redir_lseek90

redir_lseek90:
	mov	4[si],dx		; set 32-bit file offset
	mov	6[si],cx		; for return
	xchg	ax,bx			; error code in BX
	ret

redir_lseek30:				; seek mode 2: relative to end
	mov	bx,es:DHNDL_MODE[di]	; ask MSNET if anyone else can write
	and	bl,DHM_SHAREMSK		; isolate sharing bits
	cmp	bl,DHM_DENY_READ	; Only DENY_READ and DENY_NONE a
	 jb	redir_lseek40		;  problem - others might write to
	push	si			;  the file so we must ask the server
					;  how long the file is now
	mov	ax,I2F_LSEEK		; CX:DX = position now
	call	int2f_dhndl		; do a remote seek
	pop	si			; DX:AX = EOF relative position
	 jc	redir_lseek90		; (unless we have an error)
	xchg	ax,dx			; AX:DX = new EOF relative position
	xchg	ax,cx			;  and finally get into CX:DX 
	xor	ax,ax			; no problems...
	;jmps	redir_lseek90		; MYST-removed,file offset wasn't updated
	jmps	redir_lseek20		; MYST-added,go and update the new file offset.
redir_lseek40:
	add	dx,es:DHNDL_SIZELO[di]	; add file size + offset
	adc	cx,es:DHNDL_SIZEHI[di]
	jmps	redir_lseek20


eject
;	GET/SET FILE ATTRIBUTES (CHMOD)

;	+----+----+----+----+----+----+----+----+----+----+
;	|    43   |        name       |   flag  | attrib  |
;	+----+----+----+----+----+----+----+----+----+----+
;	|        size       |
;	+----+----+----+----+

;	entry:
;	------
;	name:	pointer to ASCIIZ file name
;	flag:	0 = get attribute,
;		1 = set attribute,
;	      2-5 = passwords (ignored)
;	attrib:	new attribute if flag = 1
;		password mode if flag = 3
;	
;	exit:
;	-----
;	BX:	0000 or error code ( < 0)
;	attrib:	file's attribute if flag = 0
;	size:	file's size

redir_chmod:
;-----------
;
	mov	bx,2[bp]		; BX -> parameter block
	mov	cx,8[bx]		; get attribs
	mov	bx,6[bx]		; get access flag
	mov	ax,I2F_SET_ATTR		; assume it's a set
	cmp	bl,1			; is it a set ?
	 je	redir_chmod10		; if not then
	mov	ax,I2F_GET_ATTR		; assume it's a get
	mov	cx,16h			;  with everything attribs
	 jb	redir_chmod10		;  was it ?
	mov	ax,ED_ACCESS		; no, return access denied
	jmps	redir_chmod20		;  cause it DR password stuff
redir_chmod10:
	mov	int2f_stack,cx		; attribs on the stack
	call	int2f_ldt		; do the Int 2F
	 jc	redir_chmod20
	mov	si,2[bp]		; SI -> parameter block
	mov	8[si],ax		;  return attribute
	mov	10[si],di
	mov	12[si],bx
	xor	ax,ax			;  success
redir_chmod20:
	xchg	ax,bx			; return result in BX
	ret

eject
;	GET DISK PARAMETER BLOCK

;	+----+----+----+----+----+----+----+----+----+----+
;	|    48   |  drive  |        dpb        | adjust  |
;	+----+----+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	drive:	drive to get information about

;	exit:
;	-----
;	BX:	0000 or error code ( < 0)
;	dpb:	address of DOS DPB (offset/segment)
;	adjust:	delwatch adjustment of free space

; NB. We only fill in the fields required by the Disk Free Space call.

redir_getdpb:
;------------
	mov	ax,I2F_SPACE
	call	int2f_ldt		; get the info
	 jnc	redir_getdpb10		; if we get an error then make CLMSK=FE
    mov al,0ffh        
redir_getdpb10:        
	mov	si,offset sec_pathname	; let's re-use this as a temp DPB
	dec	al			; make cluster mask
	mov	ds:DDSC_CLMSK[si],al	; and stuff into DPB
	mov	ds:DDSC_FREE[si],dx
	mov	ds:DDSC_SECSIZE[si],cx
	inc	bx			; inc number of clusters
	mov	ds:DDSC_NCLSTRS[si],bx
	mov	al,err_drv		; also fill in drive number
	mov	ds:DDSC_UNIT[si],al
	mov	si,2[bp]		; DI -> parameter block
	mov	4[si],offset sec_pathname
	mov	6[si],ds		; point to my dummy DPB
	mov	word ptr 8[si],0	; zero adjust value
	mov	bx,0ffh			; return 0xFF (ie. bad drive)
	ret

eject
;	FIND FIRST FILE

;	+----+----+----+----+----+----+----+----+----+----+
;	|    4E   |        name       |  *****  |  attrib |
;	+----+----+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	name:	pointer to ASCIIZ file name
;	attrib:	attribute to be used in search
;	
;	exit:
;	-----
;	BX:	0001 or error code ( < 0)

;	Note:	This call returns matching files in
;		the current DMA address and also saves
;		the BDOS state in the there.
;		
;		If there is space for multiple file names we
;		could return as many as will fit into the DTA
;		but it's easier just to return 1 file
;

redir_first:	; 13-find first matching file
;----------
; ONLY 1 file returned for now.....
;
	call	get_attrib_mode		; AX = mode, CX = attrib
	mov	ax,I2F_SFIRST		; srch first, valid LDT
	les	di,current_ldt
	cmp	di,-1		; valid LDT ?
	 jne	redir_first10
	mov	ax,I2F_XSFIRST		; srch first, no valid LDT
redir_first10:
	jmps	srch_buf_common

eject
;	FIND NEXT FILE

;	+----+----+
;	|    4F   |
;	+----+----+
;
;	entry:
;	------
;	
;	exit:
;	-----
;	BX:	0000 or error code ( < 0)

;	Note:	This call returns matching files in
;		the current DMA address and also saves
;		the BDOS state in the there.

redir_next:	; 14-find next matching file
;---------
; ONLY 1 file returned for now.....
;
	push ss ! pop es
	mov	di,offset srch_buf	; point ES:DI -> search buffer
	mov	ax,I2F_SNEXT
srch_buf_common:
	push	dma_offset
	push	dma_segment
	mov	dma_offset,offset srch_buf
	mov	dma_segment,ds
	call	int2f_op

	pop	dma_segment
	pop	dma_offset
	 jc	srch_buf_common10
	call	redir_save_srch_state	; if no error save state
	xor	ax,ax			;  return AX = 1 file found
srch_buf_common10:
	xchg	ax,bx			; return code in BX
	ret


redir_save_srch_state:
; On entry DS=PCMODE
	les	di,dword ptr dma_offset	; ES:DI -> search state in DMA address
	
	mov	si,offset srch_buf
	mov	cx,21			; save 1st 21 bytes
	rep	movsb

	push	si			; save name/ext
	add	si,11			; skip to name/ext
	movsb				; copy the attribute
	add	si,10			; skip reserved bytes
	movsw				; copy the time
	movsw				; copy the date
	add	si,2			; skip starting cluster
	movsw				; copy the file size
	movsw
	pop	bx			; recover name
	jmp	unparse			; unparse the name

; Restore DOS search area from user DTA
;
redir_restore_srch_state:
;------------------------
; On Entry:
;	DS = SYSDAT
; On Exit:
;	AL = 1st byte of srch buf
;	DS preserved
;
	push	ss
	pop	es
	mov	di,offset srch_buf	; ES:DI -> internal state
	push	ds
	lds	si,ss:dword ptr dma_offset
	lodsb				; DS:SI -> search state in DMA address
	stosb
	mov	cx,20			; copy 1st 21 bytes
	rep	movsb
	pop	ds
	ret

eject
;	COMMIT FILE (COMMIT)

;	+----+----+----+----+
;	|    50   |  handle |
;	+----+----+----+----+

;	entry:
;	------
;	handle:	open file handle to be flushed

;	exit:
;	-----
;	BX:	0000 or error code ( < 0)

redir_commit:
	test	es:DHNDL_MODE[bx],DHM_WO+DHM_RW
	 jz	redir_commit10		;  we don't need to commit it
	mov	ax,I2F_COMMIT
	call	int2f_dhndl		; commit this file
	 jc	redir_commit20
redir_commit10:
	xor	ax,ax			; success
redir_commit20:
	xchg	ax,bx			; return result in BX
	ret


eject
;	CREATE NEW FILE

;	+----+----+----+----+----+----+----+----+
;	|    51   |        name       |  mode   |
;	+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	name:	segmented address of ASCIIZ name
;   mode:   attribute for file 

;	exit:
;	-----
;	BX:	file handle or error code ( < 0)

;	Note:	The function is identical to CREATE FILE
;		with the exception that an error is returned
;		if the specified file already exists.

redir_mknew:
	call	get_attrib_mode		; AX = mode, CX = attrib
	xchg	ax,cx
	or	ax,120h			; set ARCHIVE + MKNEW bits
	mov	file_attrib,ax
	mov	int2f_stack,ax
	mov	int2f_cmd,I2F_CREATE
	mov	file_mode,DHM_RW	; Open Compatibility mode, Read/Write
	jmp	redir_open_create_common

eject
;	LOCK/UNLOCK FILE DATA (LOCK/UNLOCK)

;	+----+----+----+----+----+----+----+----+
;	|    52   |  handle |       offset      |
;	+----+----+----+----+----+----+----+----+
;	|       length      |   lock  |
;	+----+----+----+----+----+----+

;	entry:
;	------
;	handle:	open file handle
;	offset:	long integer offset
;	length:	long integer byte count
;	lock:	0 = lock, 1 = unlock

;	exit:
;	-----
;	BX:	byte count or error code ( < 0)

redir_lock:
; Lock uses I2F_LOCK, with CX,DX,SI as per INT 21, DI on stack
; Unlock uses I2F_UNLOCK with same.
	mov	bx,2[bp]		; BX -> parameter block
if DOS5
	push	bp
	lea	bp,4[bx]		; BP -> parameter block 
	mov	dx,bp			; as does DX
	mov	ax,I2F_LOCK
	mov	bl,ds:byte ptr 12[bx]
	mov	bh,5Ch			; lock/unlock in BX
	call	int2f_dhndl		; try the operation
	pop	bp
else
	mov	dx,ds:4[bx]		; get low word of offset in DX
	mov	cx,ds:6[bx]		;  and the hi word in CX
	mov	di,ds:8[bx]		; get low word of length in DI
	mov	si,ds:10[bx]		;  and high in SI
	mov	int2f_stack,di		; length low is on stack
	mov	ax,I2F_LOCK		; assume lock
	cmp	ds:word ptr 12[bx],0
	 je	redir_lock10
	mov	ax,I2F_UNLOCK		; no, it must be unlock
redir_lock10:
	call	int2f_dhndl		; try the operation
endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -