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

📄 redir.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 4 页
字号:
	push ds ! push bp
	mov	si,2[bp]		; SI -> parameter block
	lds	si,2[si]		; DS:SI -> user supplied name
	mov	dx,si			; DS:DX as well..
	push ss ! pop es
	mov	di,offset pri_pathname	; DI -> where to build pathname
	mov	ax,I2F_PPATH
	int	2fh			; offer path build to someone else
	pop bp ! pop ds
	ret

build_remote_path:
;-----------------
; On Entry:
;	DS:SI -> path to check
;	SS:DI -> position to build remote path
; On Exit:
;	CY clear, CX == 0 if it's a valid remote path
;	CY clear, CX <> 0 if it's a local path
;	CY set if there is an error to be returned (BX = error code)
;
	mov	cx,si			; save source path in CX
	mov	dl,ss:current_dsk	; assume current disk
	lodsw				; get 1st two characters
	test	al,al			; make sure it's not a NUL string
	 jz	build_remote_path10	;  before we check it it's a
	cmp	ah,':'			;  drive specified
	 jne	build_remote_path10	; we want to find "d:\\" format too
	mov	bx,ED_DRIVE		; assume "invalid drive" error
	and	al,not 'a'-'A'		; cheap upper case
	sub	al,'A'
	 jb	build_remote_path30	; return "invalid drive" if error
	cmp	al,ss:last_drv		; check if > 'Z'
	 ja	build_remote_path30	; return "invalid drive" if error
	xchg	ax,dx			; DL = ASCIIZ supplied drive
	lodsw				; get possible '\\'
build_remote_path10:
	mov	ss:word ptr current_ldt,0ffffh
	call	check_dslash		; is it "\\"
	 je	build_remote_path20		; if so forget about the drive #
	call	isremote		; test if drive DL is remote
if JOIN
	 jb	build_remote_path30	; return "invalid drive" if JOINed
endif
	 jnz	build_remote_path20	; it's remote, go build a path
	xor	cx,cx			; CY clear (no error)
	inc	cx			; CX <> 0, (non-remote drive)
	ret

build_remote_path20:
; Build a path from the CSD and the pathname in the parameter block
	mov	si,cx			; DS:SI -> source ASIIZ name
	push ss ! pop es		; ES:DI -> MSNET buffer
	call	redir_build_path
	 jc	build_remote_path30
	xor	cx,cx			; CY clear, CX == 0
	ret				; it's a valid remote path

build_remote_path30:
	stc				; CY set, we have error BX
	ret



eject
;	MAKE DIRECTORY (MKDIR)

;	+----+----+----+----+----+----+
;	|    39   |        name       |
;	+----+----+----+----+----+----+

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

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

redir_mkdir:
	mov	ax,I2F_MKDIR		; it's a make dir
	jmps	redir_pathop_common


eject
;	REMOVE DIRECTORY (RMDIR)

;	+----+----+----+----+----+----+
;	|    3A   |        name       |
;	+----+----+----+----+----+----+

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

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


redir_rmdir:
	mov	ax,I2F_RMDIR		; it's a remove dir
;	jmp	redir_pathop_common

redir_pathop_common:
	push	ds
	push ss ! pop ds
	call	int2f_ldt
	pop	ds
	 jc	redir_pathop_common10
	xor	ax,ax			; no problems
redir_pathop_common10:
	xchg	ax,bx			; return result in BX
	ret



eject
;	CHANGE DIRECTORY (CHDIR)

;	+----+----+----+----+----+----+
;	|    3B   |        name       |
;	+----+----+----+----+----+----+

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

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

redir_chdir:
;------------
; The following code throws out the ASSIGN/SUBST form "f:=d:\"
; The alternative is to allow the Extentions to throw it out as a bad path
; but this is safer, and doesn't cost us much.

	push	ds
	mov	bx,ED_PATH		; assume we have a problem
					; BX = ED_PATH ready for error

	mov	si,2[bp]		; SI -> parameter block
	lds	si,ds:2[si]		; DS:SI -> ASCIIZ string
	cmp	ds:word ptr 1[si],'=:'	; 'd:=' specification?
	 je	redir_chdir40

	push ss ! pop ds		; DS = PCMODE

	cmp	word ptr current_ldt,-1
	 je	redir_chdir40		; we reject any chdir of the form
					; "\\server\path"
	mov	ax,I2F_CHDIR
	call	int2f_ldt		; is this a valid path ?
	 jc	redir_chdir30
	push 	ds ! pop es
	mov	si,offset pri_pathname

; DGM - don't allow path greater than 66 chars
	mov	cx, LDT_FLAGS-LDT_NAME	; calculate max pathlen from LDT
	mov	di, si
	sub	ax,ax
	repne	scasb
	mov	ax, ED_PATH		; assume path too long
	 jne	redir_chdir30		; jump if path too long

	les	di,current_ldt		; ES:DI -> path for this drive
	call	copy_asciiz		; copy new path to LDT current dir
	xor	ax,ax			; no errors
redir_chdir30:
	xchg	ax,bx			; return result in BX
redir_chdir40:
	pop	ds
	ret


eject
;	CREATE FILE (CREAT)

;	+----+----+----+----+----+----+----+----+
;	|    3C   |        name       |  mode   |
;	+----+----+----+----+----+----+----+----+

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

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


redir_creat:
	call	get_attrib_mode		; AX = mode, CX = attrib
	xchg	ax,cx
	or	ax,20h			; set the ARCHIVE bit on create
	mov	file_attrib,ax
	mov	int2f_stack,ax		; attrib on stack
	mov	int2f_cmd,I2F_CREATE
	cmp	word ptr current_ldt,-1	; valid LDT ?
	 jne	redir_creat10		; no, modify create function
	mov	int2f_cmd,I2F_XCREATE
redir_creat10:
	jmp	redir_open_create_common


eject
;	OPEN FILE (OPEN)

;	+----+----+----+----+----+----+----+----+----+----+
;	|    3D   |        name       |  mode   |  attrib |
;	+----+----+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	name:	segmented address of ASCIIZ name
;   mode:   open mode 
;	attrib:	file attrib for search (default = 16h)

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

redir_open:
;----------
;
	call	get_attrib_mode		; AX = mode, CX = attrib
	and	ax,7fh			; remove inheritance bit
	mov	int2f_stack,ax
	mov	int2f_cmd,I2F_OPEN
redir_open_create_common:
	call	find_xfn		; get external file handle in DI
	mov	bx,ED_HANDLE		;  assume no handles
	 jc	redir_open20
	push	di
	call	redir_openfile		; now do the open
	pop	di
	 jc	redir_open20
; On Entry:
;	AL = IFN
;	DI = XFN
;	ES:BX -> DHNDL_
; On Exit:
;	PSP fixed up
;
	mov	bx,di
	call	get_xftptr		; ES:DI -> XFN table
	 jc	redir_open10		; no PSP, skip xfn stuff
	add	di,bx			; add external file #
	stosb				; update table entry
	ret

redir_open10:
	xchg	ax,bx			; no PSP, return XFN in BX
redir_open20:
	ret


redir_openfile:
;--------------
; On Entry:
;	pri_pathname and file_attrib have been set up
; On Exit:
;	AL = IFN
;	ES:BX = DHNDL_
;	CY set on error, BX = error code
; We should set up COUNT, MODE, UID, PSP, and SHARE
	call	find_dhndl		; find DHNDL_
	 jc	redir_openf40		; return if a problem with this
	push	ax			; save IFN
	push es ! push bx		; save DHNDL_

	mov	ax,file_mode
	and	al,not DHM_LOCAL
	mov	es:DHNDL_MODE[bx],ax	; save mode in DOSHNDL
	mov	es:DHNDL_SHARE[bx],0	; zero share record

	mov	ax,int2f_cmd		; either open or create
	call	int2f_dhndl		; lets try the command

	pop bx ! pop es			; recover DHNDL_
	pop	dx			; recover IFN
	 jc	redir_openf30		; on error discard the handle
	xchg	ax,dx			; return AL = IFN
	mov	es:DHNDL_COUNT[bx],1	; handle now properly in use
	mov	cx,file_mode
	test	ch,DHM_FCB/256		; is this an FCB open ?
	 jz	redir_openf10
	or	es:byte ptr DHNDL_MODE+1[bx],DHM_FCB/100h
redir_openf10:
	test	cl,DHM_LOCAL		; is it a "private" file ?
	 jz	redir_openf20
	or	es:byte ptr DHNDL_WATTR+1[bx],DHAT_LOCAL/100h
redir_openf20:
	ret

redir_openf30:
	xchg	ax,bx			;  returning error in BX
	ret

redir_openf40:
	mov	bx,ED_HANDLE		; no handles are left
	ret

eject
;	CLOSE FILE (CLOSE)

;	+----+----+----+----+
;	|    3E   |  handle |
;	+----+----+----+----+

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

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

redir_close:
;------------
;
	mov	si,2[bp]		; SI -> parameter block
	mov	ax,2[si]		; get external file #
	call	get_xftptr		; ES:DI -> xft table
	 jc	redir_close10
	add	di,ax			; add in XFN
	mov	ax,0FFh			; get "unused" value for XFT
	xchg	al,es:[di]		; release file & get internal #
redir_close10:				; we can now do the actual close
	call	ifn2dhndl		; ES:BX -> DHNDL_
	 jc	redir_close30		;  exit if error occurrs
    mov ax,es:DHNDL_COUNT[bx]   
	mov	ah,3eh			;  count, AH = 3E
	push	ax
	mov	ax,I2F_CLOSE
	call	int2f_dhndl		; close it
	pop	bx
	 jnc	redir_close20		; errors ?
	xchg	ax,bx			; recover return code
redir_close20:
	ret
redir_close30:
	mov	bx,ED_H_MATCH		; assume invalid IFN
	ret

eject
;	READ FROM FILE (READ)

;	+----+----+----+----+----+----+----+----+----+----+
;	|    3F   |  handle |       buffer      |  count  |
;	+----+----+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	handle:	open file handle
;	buffer:	buffer to read into
;	count:	max. number of bytes to read

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

redir_read:
;----------
	mov	ax,I2F_READ
redir_rw_handle:
	mov	si,2[bp]		; SI -> parameter block
	mov	cx,8[si]		; CX = Count
	push	ds
	lds	dx,4[si]		; DS:DX = DMA address
	call	redir_rw
	pop	ds
	mov	si,2[bp]		; SI -> parameter block
	mov	8[si],cx		; CX = Count
	ret

eject
;	WRITE TO FILE (WRITE)

;	+----+----+----+----+----+----+----+----+----+----+
;	|    40   |  handle |       buffer      |  count  |
;	+----+----+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	handle:	open file handle
;	buffer:	buffer to be wriiten
;	count:	max. number of bytes to write

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

redir_write:
;-----------
	mov	ax,I2F_WRITE
	jmps	redir_rw_handle

redir_rw:
;--------
; On Entry:
;	AX = command code
;	ES:BX = DHNDL_
;	CX = count
;	DS:DX = buffer
; On Exit:
;	CX = count transferred
;	BX = zero or error code
;
	cmp	ax,I2F_WRITE		; is it a write ?
	 jne	redir_rw10
	and	es:DHNDL_WATTR[bx],not (DHAT_CLEAN+DHAT_TIMEOK)
redir_rw10:
	push	ss:dma_offset
	push	ss:dma_segment
	push	cx
	mov	cl,4
	mov	di,dx			; save dma offset
	and	dx,15			; make offset within para
	shr	di,cl			; convert offset to para offset
	mov	si,ds			; add to segment
	add	di,si			; DI:DX -> DMA address
	 ja	redir_rw15		; are we within normal TPA ?
	inc	di			; no adjust to offset within
	shl	di,cl			;  magic segment FFFF
	add	dx,di
	mov	di,0ffffh		; use magic segment
redir_rw15:
	pop	cx

⌨️ 快捷键说明

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