📄 redir.a86
字号:
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 + -