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

📄 funcs.fdo

📁 一个dos操作系统DRDOS的源码
💻 FDO
📖 第 1 页 / 共 5 页
字号:
	call	check_handle		; check if legal file handle
	mov	ax,fdos_pb+4		; get 32-bit file offset
	mov	dx,fdos_pb+6		; into AX,DX
	mov	cx,fdos_pb+8		; get seek mode
	 jcxz	lseek4			; seek from beginning
	dec	cx
	 jz	lseek2			; seek from current position
	dec	cx
	 jz	lseek3			; seek from end
	mov	ax,ED_DATA		; else invalid seek mode
	jmp	fdos_error		; return error code
lseek1:
	ret				; return error code

lseek2:					; seek mode 1: relative to position
	add	ax,es:DHNDL_POSLO[bx]
	adc	dx,es:DHNDL_POSHI[bx]
	jmps	lseek4			; update new position

lseek3:					; seek mode 2: relative to end
	add	ax,es:DHNDL_SIZELO[bx]
	adc	dx,es:DHNDL_SIZEHI[bx]	; add file size + offset
lseek4:					; seek mode 0: set absolute position
	mov	es:DHNDL_POSLO[bx],ax
	mov	es:DHNDL_POSHI[bx],dx
	mov	fdos_pb+4,ax		; set return values
	mov	fdos_pb+6,dx
	ret

lseek_dev:				; jump here if character device
	mov	si,2[bp]		; SI -> parameter block
	xor	bx,bx
	mov	4[si],bx		; always return result of 0000h
	mov	6[si],bx
	ret

eject
;	GET/SET FILE ATTRIBUTES (CHMOD)

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

;	entry:
;	------
;	name:	pointer to ASCIIZ file name
;	flag:	00 = get attrib/size
;		01 = set attrib
;	attrib:	file attribute if flag=1
;
;	exit:
;	-----
;	AX:	0000 or error code ( < 0)
;	attrib:	file attribute if flag=0
;	size:	file size if flag=0
;
if PASSWORD
;	entry:
;	------
;	name:	pointer to ASCIIZ file name
;	flag:	02 = get password mode
;		03 = set pw mode/password
;		04 = get encrypted password
;		05 = set encrypted password
;	attrib:	password mode if flag = 3,5
;	dma:	ascii     password if flag = 3
;		encrypted password if flag = 5
;	
;	exit:
;	-----
;	AX:	0000 or error code ( < 0)
;	attrib:	file's attribute if flag = 0
;		password mode if flag = 2
;		encrypted password if flag = 4
endif
if UNDELETE
;	entry:
;	------
;	name:	pointer to ASCIIZ file name
;	flag:	80 = undelete file
;		81 = purge file
;	dma:	result of sucessful search
;
;	exit:
;	-----
;	AX:	0000 or error code ( < 0)
;
endif

fdos_chmod:
;----------
if UNDELETE
	mov	si,2[bp]		; SI -> parameter block
	mov	al,6[si]		; AX = flag
	sub	al,80h			; is it undelete or purge
	 jb	fdos_chmod_path		; if so set
	cmp	al,1
	 ja	fdos_chmod_path
	call	local_disk		; get MXdisk, switch stack
	call	select_from_DTA		; prepare for the search
	mov	chdblk,0		; don't assume sequential access
	dec	dcnt			; retract so we find the same entry
	call	find_pending_delete	; did we find it ?
	 jz	chmod_notfound		; No, then skip
	call	hdsblk			; AX = directory root cluster
	xchg	ax,dx			; DX = dir cluster
	mov	cx,dcnt			; CX = directory index for entry
	mov	ax,fdos_pb+6		; get operation type
	mov	ah,DELW_UNDEL		; assume we are about to undelete
	cmp	al,80h			; is it undelete ?
	 je	fdos_undelete_purge
	mov	ah,DELW_PURGE		; no, it must be purge entry
fdos_undelete_purge:
	mov	al,physical_drv		; give delwatch a chance to do it
	callf	ss:fdos_stub
	 jc	fdos_ED_FUNCTION	; return error if DELWATCH not there
	mov	fdos_ret,ax		;  else return result
	ret
fdos_chmod_path:
endif
	call	redir_asciiz_offer
	call	local_disk		; get MXdisk, switch stack

	call	path_prep		; parse the path, go to bottom level
	call	chk_no_wild		; can't have wildcards
	call	finddfcbf		; find first matching FCB
	 jnz	chmod10			; if we can't find a file/dir
	call	chk_for_root		;  check if we are in the root
	 jnz	chmod_notfound		; if so return directory attribute
	mov	cx,fdos_pb+6		;  but only for get attributes
	 jcxz	chmod_root		;  other fall through to not found
chmod_notfound:
	jmp	fdos_ED_FILE
chmod_root:
	mov	fdos_pb+8,DA_DIR	; return directory attribute
	ret

fdos_ED_FUNCTION:
	mov	ax,ED_FUNCTION		; invalid subfunction
	jmp	fdos_error

chmod10:
	mov	bx,dirp			; BX -> matching directory entry
	mov	ax,DSIZE[bx]
	mov	fdos_pb+10,ax
	mov	ax,DSIZE+WORD[bx]
	mov	fdos_pb+12,ax
	xor	ax,ax
	mov	al,DATTS[bx]		; get directory attributes
	mov	cx,fdos_pb+6		; get function #
	 jcxz	chmod30			; always allow get attribs
if PASSWORD
	cmp	cl,5			; validate sub-function number
	 ja	chmod15
	mov	ax,DPWM[bx]		; assume return password mode
	and	ax,PWM_ANY		; isolate password mode bits
	cmp	cl,2			; is it get mode ?
	 je	chmod30			; yes, just return it
	push	ax
	push	cx
	call	check_pwd_any		; check the password
	pop	cx
	pop	ax
	mov	dx,fdos_pb+8		; DX = new attributes
	cmp	cl,2			; is it get mode ?
	 ja	chmod20			; how about other password functions?
else
	cmp	cl,1			; validate sub-function number
	 ja	chmod15
	mov	dx,fdos_pb+8		; DX = new attributes
endif
; Set new file attrib
; BX = DIRP
; DX = attrib
;
	test	dl,DA_DIR		; directory bit not allowed
	 jnz	chmod12
	xor	dl,DATTS[bx]		; check which bits are changed
	and	dl,not DA_DIR		; don't check or flip directory bit
	test	dl,DA_FIXED		; trying to change the unchangeable?
	 jz	chmod13
chmod12:
	jmp	fdos_ED_ACCESS		; return "access denied"
chmod13:
	xor	DATTS[bx],dl		; set new attributes
if PASSWORD
	jmps	chmod90
else
	jmp	update_dir		; update directory
endif

chmod15:
	mov	ah,PASSWD_CHMOD		; call out to SECURITY TSR
	callf	ss:fdos_stub
	 jc	fdos_ED_FUNCTION
	jmps	chmod90

if PASSWORD
chmod20:
; Password support for functions 3-5
; BX = DIRP
; CX = flag
; DX = attrib
;
	push	bx
	push	cx
	push	dx
	mov	di,S_DENY_IF_OPEN	; check if file already open
	call	check_with_share	; and stop if it is
	pop	dx
	pop	cx
	pop	bx
	mov	ax,DPWD[bx]		; assume get encrypted password
	cmp	cl,4			;  was it ?
	 jne	chmod50
endif					; yes, return encrypted password
chmod30:
	mov	fdos_pb+8,ax
	ret


if PASSWORD
; Password support for functions 3/5
; BX = DIRP
; CX = flag
; DX = attrib
; 
chmod50:				; set password/password mode
	test	dh,80h			; assign new password?
	 jz	chmod70			; skip if mode change only
	mov	di,offset save_area	; ES:DI -> local structure
	push	ds
	call	lds_si_dmaptr		; DS:SI -> users DMA address
	lodsw				; AX = possible encrypted password
	cmp	cl,5			; was it set encrypted password ?
	 je	chmod60
	dec	si			; no, the DMA buffer contains
	dec	si			;  an 8 character password so we
	call	hash_pwd		;  compute password hash code
chmod60:
	pop	ds
	or	DATTS[bx],DA_HIDDEN	; file will be hidden
	mov	DPWD[bx],ax		; set new file password
	test	ax,ax			; null password?
	 jnz	chmod70
	xor	dx,dx			; can't be protected....
chmod70:
	mov	ax,not PWM_ANY		; clear existing file
	and	DPWM[bx],ax		;  password mode bits
	not	ax			; isolate password mode bits
	and	dx,ax			;  in new password mode
	 jz	chmod80			; if no protection, leave them off
	test	DATTS[bx],DA_DIR	; directories protected in all modes
	 jz	chmod80			; skip if not a directory
	xchg	ax,dx			; force all modes on
chmod80:
	or	DPWM[bx],dx		; set password mode bits
	test	dx,dx			; test if protection enabled
	 jnz	chmod90			; skip if any protection still active
	mov	DPWD[bx],dx		; remove the password and hidden bit
	and	DATTS[bx],not DA_HIDDEN	;  as file is no longer protected
endif
chmod90:
	jmp	update_dir		; now update the directory






eject
;	DUPLICATE FILE HANDLE (DUP)

;	+----+----+----+----+----+----+
;	|    45   |  handle |  newhnd |
;	+----+----+----+----+----+----+

;	entry:
;	------
;	handle:	open file handle

;	exit:
;	-----
;	newhnd: new file handle
;	AX:	duplicate file handle or error code ( < 0)

fdos_dup:
;--------
	call	find_xfn		; find new external file #
	mov	si,2[bp]		; SI -> parameter block
	mov	ds:4[si],di		; save new handle #
	 jnc	fdos_fdup		; share the code with DUP2
	mov	bx,ED_HANDLE		; can't find a handle
	ret
eject
;	FORCE DUPLICATE FILE HANDLE (DUP2)

;	+----+----+----+----+----+----+
;	|    46   |  handle |  newhnd |
;	+----+----+----+----+----+----+

;	entry:
;	------
;	handle:	open file handle
;	newhnd: new file handle

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

fdos_fdup:
;---------
	call	vfy_dhndl_ptr		; check file handle #
	call	local_disk		; get critical section locks
	call	get_xftptr		; ES:DI -> XFN table
	 jc	dup_err			; we need one..
	mov	bx,fdos_pb+4		; get user file number (0-19)
	cmp	bx,cx			; is it sensible ?
	 jae	dup_err
	cmp	es:byte ptr [di+bx],0FFh
	 jne	dup_err			; handle should be closed by PCMODE..
	call	check_handle		; check if legal file handle
	inc	es:DHNDL_COUNT[bx]	; another user
	call	dup_dev			; inform device driver it's happened
	call	get_xftptr		; ES:DI -> XFT's
	mov	bx,fdos_pb+2		; get XFN to dup from
	mov	al,es:[di+bx]		; get it's IFN
	mov	bx,fdos_pb+4		; BX = XFN to dup to
	mov	es:[di+bx],al		; it gets same IFN
	mov	fdos_ret,bx		; return XFN to caller
	ret

dup_err:				; complain someone stole my handle
	jmp	fdos_ED_H_MATCH

eject
;	GET CURRENT DIRECTORY
;	
;	+----+----+----+----+----+----+----+----+
;	|    47   |   drive |        path       |
;	+----+----+----+----+----+----+----+----+

;	entry:
;	------
;	drive:	drive to get path for
;	path:	address of 64 byte path buffer to be
;		filled in with current path

;	exit:
;	-----
;	BX:	0100 or error code

fdos_curdir:
;-----------
	call	local_disk		; it's a disk function
	call	get_pb2_drive		; get specified drive in AL
	call	get_ldt			; ES:BX -> LDT_ for drive
	 jc	fdos_curdir30
	mov	dx,es:LDT_FLAGS[bx]
	test	dx,LFLG_NETWRKD
	 jnz	fdos_curdir10
	test	dx,LFLG_PHYSICAL
	 jz	fdos_curdir30
	call	select_unique		; select the drive for media changes
	les	bx,ss:current_ldt	; ES:BX -> LDT_ for this drive
	cmp	es:LDT_BLK[bx],0FFFFh	; is LDT valid
	 jne	fdos_curdir10
	call	rebuild_ldt_curdir	; no, better rebuild it
fdos_curdir10:
	push	ds
	push es ! push bx		; save LDT
	les	di,dword ptr fdos_pb+4	; ES:DI -> destination buffer
	pop si ! pop ds			; DS:SI -> LDT
	add	si,ds:LDT_ROOTLEN[si]	; skip the '\\server\dir'
	lodsb				; eat the slash
	call	check_slash		; if it is one..
	 je	fdos_curdir20
	dec	si			; I didn't mean it!
fdos_curdir20:
	call	copy_asciiz		; copy the string
	pop	ds
	mov	fdos_ret,100h		; return 100h for success
    ret      

fdos_curdir30:
	jmp	fdos_ED_DRIVE		; naughty - it's a bad drive


eject
;	GET DISK PARAMETER BLOCK

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

;	entry:
;	------
;	drive:	drive to get information about
;		(top bit of word set if free space not required)

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

fdos_getdpb:
;-----------
	call	redir_drv_offer
	call	local_disk		; get MXdisk, switch stack
	call	get_pb2_drive		; get drive from parameter block
	call	logical2physical	; AX = physical drive
	call	select_physical_drv
	test	fdos_pb+2,8000h		; free space required ?
	 jnz	fdos_getdpb10
	call	update_ddsc_free	; then make sure it is up to date
if DELWATCH
	xor	cx,cx			; assume no adjustment
	mov	ah,DELW_SPACE
	mov	al,physical_drv		; now we call DELWATCH to
	callf	fdos_stub		;  add pending deletes
	mov	fdos_pb+8,cx		; return free space adjust value
endif
fdos_getdpb10:
	les	ax,ss:current_ddsc
	mov	fdos_pb+4,ax
	mov	fdos_pb+6,es
	ret

eject
;	FLUSH BUFFERS

;	+----+----+
;	|    49   |
;	+----+----+

;	entry:
;	------
;	none

;	exit:
;	-----
;	none

fdos_flush:
;----------
	call	local_disk		; be alone...
fdos_flush_local:
; Entry point for people who already have the MX disk
	xor	dx,dx			; starting with drive A
fdos_flush10:
	push	dx
	call	mark_ldt_unsure		; ask for LDT's to be relogged
	xchg	ax,dx			; AL = drive to check
	mov	ah,BF_DIRTY
	call	buffers_check		; any buffers on this drive?
	 jz	fdos_flush20		; skip flush if none
	call	select_physical_drv	; select drive in AL
	call	update_fat		; flush all FAT buffers
;	call	update_dir		; dir always up to date
	call	update_dat		; flush all data buffers
fdos_flush20:

⌨️ 快捷键说明

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