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

📄 redir.a86

📁 与MS-DOS兼容的DOS操作系统
💻 A86
📖 第 1 页 / 共 4 页
字号:
title 'REDIR - DOS file system network redirector interace support'
;    File              : $REDIR.A86$
;
;    Description       :
;
;    Original Author   : DIGITAL RESEARCH
;
;    Last Edited By    : $CALDERA$
;
;-----------------------------------------------------------------------;
;    Copyright Work of Caldera, Inc. All Rights Reserved.
;      
;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
;    CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
;    *** Current Edit History ***
;    *** End of Current Edit History ***
;    $Log: $
;    REDIR.A86 1.30 94/12/01 10:05:21 
;    added attribute support for open/move/unlink  
;    REDIR.A86 1.29 94/11/11 15:10:03
;    Code at redir_lseek30 changed to ensure that the file offset is 
;    updated. Previously, this did not happen when INT 21/4202 (seek from
;    end of file) was called, and consequently the game MYST could not 
;    be installed under NWDOS7.    
;    REDIR.A86 1.28 94/10/03 15:41:12
;    fix problem where VLM network mapping gets deleted if you try to access
;    a path greater than 66 characters long on a network drive.
;    REDIR.A86 1.27 94/02/22 18:05:09
;    fix problem with "d:\\filename.ext" (Netware 4 LOGIN)
;    REDIR.A86 1.26 94/01/10 16:42:16
;    File delete uses file attributes of 06, not 16 (no directory bit)
;    REDIR.A86 1.25 93/12/10 00:03:09
;    Move non-inherited bit to correct place in file handle
;    REDIR.A86 1.22 93/11/19 23:59:00
;    If a read/write returns ED_LOCKFAIL turn into ED_ACCESS on shared files
;    REDIR.A86 1.21 93/09/24 19:50:50
;    Tidy up code on rename
;    REDIR.A86 1.15 93/06/16 16:22:21
;    Always initialise file search attributes to 16h (ie. sys+hidden+dir)
;    REDIR.A86 1.14 93/06/11 15:08:09
;    Return 0 from search first/next
;    REDIR.A86 1.13 93/06/11 02:06:53
;    zero space adjust on getddsc
;    ENDLOG

	eject ! include i:psp.def
	eject ! include i:fdos.equ
	eject ! include i:msdos.equ
	eject ! include i:mserror.equ
	eject ! include i:doshndl.def	; DOS Handle Structures
	eject ! include i:f52data.def	; DRDOS Structures
	eject ! include i:redir.equ

FD_EXPAND	equ	55h

	eject

PCMODE_DATA	dseg

	extrn	current_dsk:byte
	extrn	current_ddsc:dword
	extrn	current_dhndl:dword
	extrn	current_filepos:dword
	extrn	current_ldt:dword
	extrn	dma_offset:word
	extrn	dma_segment:word
	extrn	err_drv:byte
	extrn	file_attrib:word
	extrn	ldt_ptr:dword
	extrn	last_drv:byte
	extrn	phys_drv:byte
	extrn	pri_pathname:byte
	extrn	remote_call:word
	extrn	sec_pathname:byte
	extrn	srch_buf:byte
	
; Data for some int2f commands

	extrn	int2f_cmd:word
	extrn	int2f_stack:word
	extrn	file_mode:word

BDOS_CODE	cseg

	Public	islocal
	Public	redir_asciiz_dev_offer
	Public	redir_asciiz_offer
	Public	redir_asciiz_file_offer

	Public	redir_drv_offer
	Public	redir_dhndl_offer
	Public	redir_move_offer
	Public	redir_snext_offer

	extrn	toupper:near
	extrn	check_delim:near
	extrn	check_slash:near
	extrn	check_dslash:near
	extrn	copy_asciiz:near
	extrn	unparse:near
	extrn	find_xfn:near
	extrn	find_dhndl:near
	extrn	ifn2dhndl:near
	extrn	get_xftptr:near
if KANJI
	extrn	dbcs_lead:near
endif


redir_dhndl_offer:
;================
; The FDOS has called this hook to see if we are operating on an MSNET drive.
; We return if we are not, or stay and process function here if we are
	test	es:byte ptr DHNDL_WATTR+1[bx],DHAT_REMOTE/100h
	 jnz	redir_dhndl_accept
	ret
redir_dhndl_accept:
; copy some info from DHNDL_ to local variables
	push	ds
	push ss ! pop ds
	mov	ax,es:DHNDL_DEVOFF[bx]
	mov	word ptr current_ddsc,ax
	mov	ax,es:word ptr DHNDL_DEVSEG[bx]
	mov	word ptr current_ddsc+WORD,ax
	mov	ax,es:word ptr DHNDL_POS[bx]
	mov	word ptr current_filepos,ax
	mov	ax,es:word ptr DHNDL_POS+2[bx]
	mov	word ptr current_filepos+2,ax
	pop	ds
	jmps	redir_accept		; now we can process the call


redir_asciiz_dev_offer:
;======================
; The FDOS has called this hook to see if we are opening a redirected device.
; We return if we are not, or stay and process function here if we are

; Before we build it all ourselves do the appropriate INT 2F to allow
; other people to process the path themselves

	call	redir_dev_check		; is it a device ?
	 jnc	redir_accept		; it's been recognised
	ret

redir_move_offer:
;================
; The FDOS has called this hook to see if the rename operation is on a
; redirected drive. Lantastic relies on the path check broadcast's being
; done in the order new_name, old_name.

	mov	word ptr current_ldt,0ffffh
	mov	err_drv,DHAT_DRVMSK
	push	ds
	mov	si,2[bp]		; SI -> parameter block
	lds	si,10[si]		; DS:SI -> user supplied name
	push ss ! pop es
	mov	di,offset sec_pathname	; DI -> where to build pathname
	push ds ! push si ! push di ! push bp
	mov	ax,I2F_PPATH
	int	2fh			; offer path build to someone else
	pop bp ! pop di ! pop si ! pop ds
	mov	cx,0			; if accepted then it's a remote drive
	 jnc	redir_move_offer10
	call	build_remote_path	; build path if it a remote drive
redir_move_offer10:
	pop	ds
	 jc	redir_asciiz_error	; return error's if we have any
	 jcxz	redir_asciiz_offer	; it's a valid remote path
	ret				; it's not a remote path

redir_asciiz_offer:
;==================
; The FDOS has called this hook to see if we are operating on an redirected
; drive. We return if we are not, or stay and process function here if we are.
	call	redir_dev_check		; is it a device ?
	 jnc	redir_accept		; it's been recognised
;	jmp	redir_asciiz_file_offer	; now try offering as a file

redir_asciiz_file_offer:
;=======================
;	entry:	SS:BP -> function #, parameter address
;		1st level call (MXdisk not owned)
;	exit:	ZF = 1 if not networked
;
; This function is only called after an Int 2F/I2F_PPATH callout has been
; made and failed. On some functions (Open/Create) we do a check for devices
; between the redir_dev_offer and redir_asciiz_file offer

; We look for a "\\" as the start of "\\server\dir\file" form

	push	ds			; save DS
	mov	si,2[bp]		; SI -> parameter block
	lds	si,2[si]		; get ASCIIZ # from parameter block
	mov	di,offset pri_pathname	; SS:DI -> path buffer
	call	build_remote_path	; build path if it a remote drive
	pop	ds			; restore DS
	 jc	redir_asciiz_error	; return error's if we have any
	 jcxz	redir_accept		; it's a valid remote path
	ret				; it's not a remote path

redir_asciiz_error:
; On Entry:
;	BX = error code
;	DS on stack
; On Exit:
;	DS restored, BX preserved
;	near return on stack discarded, and error returned to fdos_entry
;
	pop	ax			; discard "offer" near ret
	ret				; drop straight back to caller

redir_drv_offer:
;===============
; The FDOS has called this hook to see if we are operating on an MSNET drive.
; We return if we are not, or stay and process function here if we are
;
;	entry:	SS:BP -> function #, parameter address
;		(MXdisk not owned)
;	exit:	return if not networked

	mov	dl,current_dsk		; assume it's the default drive
	mov	si,2[bp]		; SI -> parameter block
	mov	ax,2[si]		; get drive # from parameter block
	test	al,al			; test if default drive
	 jz	redir_drv_offer10	; skip if default drive
	dec	ax			; else decrement for 0..26
	xchg	ax,dx			; and use that
redir_drv_offer10:
	call	isremote
	 jnz	redir_accept
	ret				; return if not

redir_snext_offer:
;=================
; The FDOS has called this hook to see if we are operating on an MSNET drive.
; We return if we are not, or stay and process function here if we are

	call	redir_restore_srch_state
	test	al,80h			; MSNET drive ?
	 jnz	redir_accept
	ret


redir_accept:
;============
; We have decided to accept an FDOS function.
; Note by this time the functions have been validated as legal
	mov	file_attrib,16h		; default search attribs to all
	pop	si			; discard the near return address
	mov	si,2[bp]		; SI -> parameter block
	mov	si,ds:[si]		; fdos code number
	add	si,si			; make it a word offset
	jmp	cs:redir_tbl-(39h*WORD)[si]	; call the relevant function


redir_badfunc:
;-------------
	mov	bx,ED_FUNCTION		; bad function number
	ret				; (shouldn't get here...)

redir_tbl	dw	redir_mkdir	; 39-make directory
		dw	redir_rmdir	; 3A-remove directory
 		dw	redir_chdir	; 3B-change directory
		dw	redir_creat	; 3C-create file
		dw	redir_open	; 3D-open file
		dw	redir_close	; 3E-close file
		dw	redir_read	; 3F-read from file
		dw	redir_write	; 40-write to file
		dw	redir_unlink	; 41-delete file
		dw	redir_lseek	; 42-set file pointer
		dw	redir_chmod	; 43-get/set file attributes
		dw	redir_badfunc	; 44-IOCTL emulation
		dw	redir_badfunc	; 45-duplicate handle
		dw	redir_badfunc	; 46-force duplicate handle
		dw	redir_badfunc	; 47-get current directory
		dw	redir_getdpb	;*48*disk information
		dw	redir_badfunc	;*49*flush buffers
		dw	redir_badfunc	;*4A*drive select
		dw	redir_badfunc	;*4B*create child PSP
		dw	redir_badfunc	;*4C*close child PSP
		dw	redir_badfunc	;*4D*generic FCB call
		dw	redir_first	; 4E-find first matching file
		dw	redir_next	; 4F-find next matching file
		dw	redir_commit	;*50*commit file
		dw	redir_mknew	;*51*make new file
		dw	redir_lock	;*52*lock/unlock block
		dw	redir_badfunc	; 53 build DDSC from BPB
		dw	redir_badfunc	;*54*Int 25/26 emulation
		dw	redir_expand	; 55 expand file name
		dw	redir_move	; 56-rename file
		dw	redir_dattim	; 57-get/set file name

	Public	get_ldt

; To support func5D00 remote server calls we must bypass the LDT and
; go directly to the physical drive. To allow support of CDROM's etc
; on servers we do use the LDT's where no corresonding physical drive
; exists.

get_ldt:
;-------
; On Entry:
;	AL = drive (0 based)
; On Exit:
;	ES:BX -> LDT for that drive, set CY if no valid LDT
;	(All other regs preserved)
;
	cmp	al,ss:phys_drv		; if there is no conflict with
	 jae	get_ldt_raw		;  physical drives it's OK
	test	ss:remote_call,0ffh	; remote calls must get to physical
	 jz	get_ldt_raw		;  for server support
	mov	bx,ED_DRIVE		; invalid drive
	stc				; no-go
	ret

	Public	get_ldt_raw

get_ldt_raw:
;-----------
; On Entry:
;	AL = drive (0 based)
; On Exit:
;	ES:BX -> LDT for that drive, set CY if no valid LDT
;	(All other regs preserved)
;
	push	ax
	mov	bx,ED_DRIVE		; assume invalid drive
	cmp	al,ss:last_drv		; do we have an LDT for this drive ?
	 jae	get_ldt10		;  if not we can't have an LDT
	cmp	ss:word ptr ldt_ptr+2,0	; are the LDT's allocated yet ?
	 je	get_ldt10		;  if not return an error
	mov	bl,LDT_LEN
	mul	bl			; AX = offset of LDT entry for drive
	les	bx,ss:ldt_ptr		; get base of LDT's
	add	bx,ax			; DS:BX -> LDT for this drive
	stc				; ie. CLC on exit
get_ldt10:
	cmc
	pop	ax
	ret

get_ldt_flags:
;-------------
;	entry:	DL = drive number
;	exit:	AX = LDT_FLAGS entry for that drive
;		(All other regs preserved)
;
	push	es
	push	bx
	xor	ax,ax			; assume no LDT around...
	xchg	ax,dx			; AL = drive number
	call	get_ldt			; ES:BX -> LDT
	xchg	ax,dx			; restore drive to DX
	 jc	glf10			; AX = zero if no LDT
	mov	ss:word ptr current_ldt,bx ; set current_ldt
	mov	ss:word ptr current_ldt+2,es
	mov	ax,es:LDT_FLAGS[bx]	; return real flags
glf10:
	pop	bx
	pop	es
	ret
	
islocal:
;-------
;	entry:	AL = drive number (zero based)
;	exit:	CY = set if drive is remote
;		(All other regs preserved)
;
	push	ax
	push	dx
	xchg	ax,dx
	call	get_ldt_flags
if JOIN
	test	ax,LFLG_JOINED+LFLG_NETWRKD
					; are REMOTE/JOINED bits set ?
else
	test	ax,LFLG_NETWRKD		; is REMOTE bit set ?
endif
	 jz	islocal10
	stc				; indicate it's not local
islocal10:
	pop	dx
	pop	ax
	ret

isremote:
;--------
;	entry:	DL = drive number
;	exit:	ZF = clear if drive is remote
;		CY = set if drive is JOIN'd
;		(Only AX corrupted)
;
	call	get_ldt_flags
if JOIN
	test	ax,LFLG_JOINED		; is JOINED bit set ?
	 jnz	isremote10
endif
	test	ax,LFLG_NETWRKD		; is REMOTE bit set ?
	ret
if JOIN
isremote10:
	test	ax,LFLG_NETWRKD		; is REMOTE bit set ?
	stc				; STC to indicate JOIN'd
	ret
endif

redir_dev_check:
;---------------
; Offer the name to the network as a device
; On Entry:
;	PB+2 = dword ptr to ascii name
;	DI -> buffer to parse into
; On Exit:
;	CY set if not recognised
;
	mov	word ptr current_ldt,0ffffh
	mov	err_drv,DHAT_DRVMSK

⌨️ 快捷键说明

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