mirror of
https://github.com/SEPPDROID/DR-DOS-OpenDOS.git
synced 2025-10-22 16:04:20 +00:00
Upload
This commit is contained in:
503
IBMDOS/FIOCTL.A86
Normal file
503
IBMDOS/FIOCTL.A86
Normal file
@@ -0,0 +1,503 @@
|
||||
title 'FDOS IOCTL - DOS file system input/output control'
|
||||
; File : $FIOCTL.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$
|
||||
; FIOCTL.A86 1.18 93/12/09 23:39:17
|
||||
; Move non-inherited bit to correct place in file handle
|
||||
; FIOCTL.A86 1.17 93/11/03 13:38:29
|
||||
; Int 21 4409 return 0x0080 if drive is joined
|
||||
; FIOCTL.A86 1.16 93/11/02 18:04:17
|
||||
; Int21/4400 from file returns AH=0
|
||||
; FIOCTL.A86 1.15 93/09/14 20:03:15
|
||||
; Trust LFLG_PHYSICAL
|
||||
; FIOCTL.A86 1.12 93/06/17 22:11:50
|
||||
; support for ioctl 10/11 query ioctl support
|
||||
; FIOCTL.A86 1.11 93/06/16 16:21:37
|
||||
; Codepage preparation bug fixed
|
||||
; ENDLOG
|
||||
|
||||
; Date Modification
|
||||
; --------- ---------------------------------------
|
||||
; 29 Jun 89 Initial version splits from FDOS
|
||||
; 21 Nov 89 iocE/F use relative unit number
|
||||
; 12 Dec 89 ioc2/3 zero the unused portions of req hdr
|
||||
; save a few bytes in other ioc's while I'm here
|
||||
; 4 Jun 90 default file access permissions and user group support
|
||||
; 5 Jun 90 ioc0/1 tidied up
|
||||
; 12 Jun 90 get_doshndl parameter in BX not AX
|
||||
; 2 Oct 90 net_vec moves to per-VC basis (info held in CCB_)
|
||||
; 13 feb 91 ioc1 tests FHIO_DEV, not HM_DEV, (123 MSNet printing)
|
||||
; 7 may 91 ioc2,ioc3,ioc6,ioc7,iocC destabilised for Lanstatic
|
||||
; by-product is ioc6 for disks returns read-ahead char
|
||||
; in AH
|
||||
; 28 feb 92 ioctl C checks bit 6 not bit 14 in DH_ATTRIB
|
||||
; 3 aug 92 ioctl C/D pass thru' SI/DI
|
||||
; 5 aug 92 substatial ioctl rework saves a few bytes - ioctl
|
||||
; request header now built by PCMODE
|
||||
|
||||
eject ! include i:fdos.equ
|
||||
eject ! include rh.equ
|
||||
eject ! include i:msdos.equ
|
||||
eject ! include i:mserror.equ
|
||||
eject ! include i:doshndl.def ; DOS Handle Structures
|
||||
eject ! include i:driver.equ
|
||||
eject ! include i:f52data.def ; DRDOS Structures
|
||||
eject
|
||||
|
||||
|
||||
PCMODE_DATA dseg BYTE
|
||||
extrn ioctlRH:byte ; request header is build in PCMODE
|
||||
; data area
|
||||
|
||||
BDOS_DATA dseg word
|
||||
extrn fdos_pb:word
|
||||
extrn fdos_ret:word
|
||||
extrn last_drv:byte
|
||||
extrn req_hdr:byte
|
||||
if PASSWORD
|
||||
extrn global_password:word
|
||||
endif
|
||||
|
||||
BDOS_CODE cseg
|
||||
|
||||
extrn local_disk:near
|
||||
extrn device_driver:near
|
||||
extrn block_device_driver:near
|
||||
extrn fdos_error:near
|
||||
extrn fdos_ED_DRIVE:near
|
||||
extrn fdos_ED_FUNCTION:near
|
||||
extrn fdos_read:near
|
||||
extrn get_ddsc:near
|
||||
extrn vfy_dhndl_ptr:near
|
||||
extrn get_pb2_drive:near
|
||||
extrn ioc6_dev:near ; IOCTL(6): input status for device
|
||||
extrn ioc7_dev:near ; IOCTL(7): output status for device
|
||||
extrn vfy_dhndl_ptr:near
|
||||
extrn verify_handle:near
|
||||
extrn reload_registers:near
|
||||
if JOIN
|
||||
extrn get_ldt:near
|
||||
endif
|
||||
if PASSWORD
|
||||
extrn hash_pwd:near
|
||||
endif
|
||||
|
||||
public fdos_ioctl
|
||||
|
||||
eject
|
||||
; INPUT/OUTPUT CONTROL (IOCTL)
|
||||
|
||||
; +----+----+----+----+----+----+----+----+----+----+
|
||||
; | 26 | param | func | request header |
|
||||
; +----+----+----+----+----+----+----+----+----+----+
|
||||
|
||||
|
||||
; entry:
|
||||
; ------
|
||||
; param: handle/drive on some functions
|
||||
; func: sub function (0-A)
|
||||
; request header: far pointer to IOCTL request header
|
||||
|
||||
; exit:
|
||||
; -----
|
||||
; AX: return code or error code ( < 0)
|
||||
; param: return value from some functions
|
||||
|
||||
|
||||
|
||||
ioctl_tbl dw ioctl0 ; 0-get handle status
|
||||
dw ioctl1 ; 1-set handle status
|
||||
dw ioctl2 ; 2-receive control string (handle)
|
||||
dw ioctl3 ; 3-send control string (handle)
|
||||
dw ioctl4 ; 4-receive control string (drive)
|
||||
dw ioctl5 ; 5-send control string (drive)
|
||||
dw ioctl6 ; 6-input status
|
||||
dw ioctl7 ; 7-output status
|
||||
dw ioctl8 ; 8-removable media check
|
||||
dw ioctl9 ; 9-networked drive check
|
||||
dw ioctlA ; A-networked handle check
|
||||
if PASSWORD
|
||||
dw ioctl54 ; B-set global password
|
||||
else
|
||||
dw device_ED_FUNCTION
|
||||
endif
|
||||
dw ioctlC ; C-code page support
|
||||
dw ioctlD ; D-generic IOCTL disk i/o
|
||||
dw ioctlE ; E-get logical drive
|
||||
dw ioctlF ; F-set logical drive
|
||||
dw ioctl10 ; 10-query IOCTL for char devs
|
||||
dw ioctl11 ; 11-query IOCTL for disks
|
||||
|
||||
NUM_IOCTL equ (offset $ - offset ioctl_tbl)/WORD
|
||||
|
||||
|
||||
|
||||
fdos_ioctl:
|
||||
;----------
|
||||
mov bx,2[bp] ; BX -> parameter block
|
||||
mov bx,4[bx] ; get I/O control subfunction
|
||||
cmp bx,NUM_IOCTL ; is it in the supported range?
|
||||
jae device_ED_FUNCTION ; skip if value too large
|
||||
shl bx,1 ; else make it word index
|
||||
jmp ioctl_tbl[bx] ; call the right function
|
||||
device_ED_FUNCTION:
|
||||
mov bx,ED_FUNCTION ; "invalid function"
|
||||
ret
|
||||
|
||||
|
||||
|
||||
ioctl0: ; get device status
|
||||
;------
|
||||
; Note: We store the binary flag for the standard console
|
||||
; handles in the console mode, not in the file handle,
|
||||
; as the handles are shared across all consoles...
|
||||
|
||||
call vfy_dhndl_ptr ; check if good handle
|
||||
mov ax,es:DHNDL_WATTR[bx] ; get attrib from doshndl
|
||||
test ah,DHAT_REMOTE/256
|
||||
mov ah,0 ; files/networks return 0 in AH/DH
|
||||
jnz device_OK ; return attrib if network device
|
||||
test al,DHAT_DEV ; or a file
|
||||
jz device_OK
|
||||
les bx,es:DHNDL_DEVPTR[bx] ; get real device driver address
|
||||
mov ah,es:byte ptr 5[bx] ; get device driver attribute
|
||||
; jmp device_OK
|
||||
|
||||
device_OK:
|
||||
;---------
|
||||
mov bx,2[bp] ; get parameter block address
|
||||
mov 6[bx],ax ; save returned status
|
||||
xor bx,bx ; successful return code
|
||||
ret
|
||||
|
||||
ioctl1: ; set device status
|
||||
;------
|
||||
call vfy_dhndl_ptr ; make sure this is an open handle
|
||||
test es:DHNDL_WATTR[bx],DHAT_DEV
|
||||
jz device_ED_FUNCTION ; can't set status of disk files
|
||||
mov ax,word ptr ioctlRH+14
|
||||
; pick up new device status
|
||||
test ah,ah ; test if high byte is zero
|
||||
jnz device_ED_FUNCTION ; skip if O.K.
|
||||
or al,DHAT_DEV ; make sure it stays a device
|
||||
mov es:DHNDL_ATTR[bx],al ; store ioctl state in doshndl
|
||||
jmps device_OK ; success
|
||||
|
||||
|
||||
ioctl2: ; receive control string (devicehandle)
|
||||
;------
|
||||
ioctl3: ; send control string (device handle)
|
||||
;------
|
||||
ioctlC: ; generic ioctl (device handle)
|
||||
;------
|
||||
ioctl10: ; query ioctl support (device handle)
|
||||
;-------
|
||||
call vfy_dhndl_ptr ; check file handle #
|
||||
call local_disk ; get MXdisk
|
||||
call verify_handle ; make sure the handle is good
|
||||
jnc short_fdos_ED_FUNCTION ; and is for a DEVICE
|
||||
xor cx,cx ; device relative unit # always zero
|
||||
les si,es:DHNDL_DEVPTR[bx] ; ES:SI -> device driver
|
||||
jmps ioc2345CDcommon ; now use common code
|
||||
|
||||
ioctl4: ; receive control string (drive)
|
||||
;------
|
||||
ioctl5: ; send control string (drive)
|
||||
;------
|
||||
ioctlD: ; generic ioctl (drive)
|
||||
;------
|
||||
ioctl11: ; query ioctl support (drive)
|
||||
;-------
|
||||
call local_disk ; get MXdisk, switch stack
|
||||
call get_pb2_ddsc ; get drives DDSC_
|
||||
mov cl,es:DDSC_RUNIT[bx] ; get relative unit #
|
||||
les si,es:DDSC_DEVHEAD[bx] ; ES:SI -> device header
|
||||
; jmps ioctl2345Common ; now use common code
|
||||
|
||||
ioc2345CDcommon:
|
||||
;---------------
|
||||
; On Entry:
|
||||
; ES:SI -> device driver header
|
||||
; CL = media byte (0 if character device)
|
||||
; CH = relative unit (0 if character device)
|
||||
; MXDisk obtained
|
||||
; On Exit:
|
||||
; IOCTL performed
|
||||
;
|
||||
mov ax,fdos_pb+6 ; device driver support required
|
||||
test es:DH_ATTRIB[si],ax ; does device driver support function ?
|
||||
jz short_fdos_ED_FUNCTION
|
||||
push ds
|
||||
push es ! pop ds ; DS:SI -> device driver
|
||||
push ss ! pop es
|
||||
mov bx,offset ioctlRH ; ES:BX -> request header
|
||||
mov es:RH_UNIT[bx],cl ; set relative unit for block devices
|
||||
call device_driver ; call the device driver
|
||||
pop ds ; check for errors on return
|
||||
; jmp fdos_error_check
|
||||
|
||||
fdos_error_check:
|
||||
;-------------
|
||||
; On Entry:
|
||||
; AX = Req Status
|
||||
; On Exit:
|
||||
; SIGN set if an error, AX&BX = Internal DOS error code
|
||||
;
|
||||
test ax,ax ; top bit == 1 if error
|
||||
jns fdos_ioc_ec10 ; skip if no errors
|
||||
xor ah,ah
|
||||
add ax,-ED_PROTECT
|
||||
neg ax
|
||||
jmp fdos_error ; return critical error
|
||||
fdos_ioc_ec10:
|
||||
ret
|
||||
|
||||
; IOCTL subfunctions:
|
||||
|
||||
|
||||
get_pb2_ddsc:
|
||||
;------------
|
||||
; On Entry:
|
||||
; local_disk called, pick us drive from pb2
|
||||
; On Exit:
|
||||
; ES:BX -> DDSC_ for the drive
|
||||
;
|
||||
call get_pb2_drive ; get specified drive
|
||||
cmp al,last_drv ; is it a valid drive
|
||||
ja bad_drive
|
||||
call get_ldt ; ES:BX -> LDT for this drive
|
||||
jc get_pb2_ddsc10 ; no LDT, physical=logical
|
||||
mov ax,es:LDT_FLAGS[bx]
|
||||
test ah,LFLG_NETWRKD/256
|
||||
jnz short_fdos_ED_FUNCTION ; reject network drives
|
||||
test ah,LFLG_PHYSICAL/256
|
||||
jz bad_drive
|
||||
test ah,LFLG_JOINED/256
|
||||
jnz bad_drive ; reject JOIN'd drives
|
||||
mov al,es:LDT_NAME[bx] ; get physical drive from LDT
|
||||
and al,1Fh ; convert to 1 based drive
|
||||
dec ax ; make that zero based
|
||||
get_pb2_ddsc10:
|
||||
call get_ddsc ; ES:BX -> DDSC_
|
||||
jc bad_drive ; or does it?
|
||||
ret
|
||||
|
||||
bad_drive:
|
||||
jmp fdos_ED_DRIVE ; invalid drive specified
|
||||
|
||||
short_fdos_ED_FUNCTION:
|
||||
jmp fdos_ED_FUNCTION
|
||||
|
||||
|
||||
ioctl8: ; removable media check
|
||||
;------
|
||||
call local_disk ; get MXdisk, switch stack
|
||||
call get_pb2_ddsc ; get drives DDSC_
|
||||
push ds
|
||||
lds si,es:DDSC_DEVHEAD[bx] ; DS:SI -> device driver
|
||||
test ds:DH_ATTRIB[si],DA_REMOVE
|
||||
pop ds ; do we support the check ?
|
||||
jz short_fdos_ED_FUNCTION ; if we don't then don't ask
|
||||
mov req_hdr,RH15_LEN
|
||||
mov req_hdr+2,CMD_FIXED_MEDIA
|
||||
call block_device_driver ; call the device driver
|
||||
js short_fdos_ED_FUNCTION
|
||||
and ax,RHS_BUSY ; BUSY bit set if permanent - we just
|
||||
xchg ah,al ; need to get bit in the right place
|
||||
shr ax,1 ; now 1 if permanent media
|
||||
mov fdos_pb+6,ax ; return status removable (=0)
|
||||
ioctl8_10:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
ioctl6: ; file input status
|
||||
;------
|
||||
call vfy_dhndl_ptr ; make sure this is an open handle
|
||||
mov ax,es:DHNDL_WATTR[bx]
|
||||
test ax,DHAT_REMOTE
|
||||
jnz ioctl6_10 ; always ask networked handles
|
||||
test ax,DHAT_DEV
|
||||
jz ioctl6_10 ; files are always askable
|
||||
jmp ioc6_dev
|
||||
|
||||
ioctl6_10: ; disk files/network devices
|
||||
push es:DHNDL_POSLO[bx] ; save current position in file
|
||||
push es:DHNDL_POSHI[bx] ; so we can read ahead
|
||||
push es
|
||||
push bx ; save DHNDL_ too..
|
||||
push bp ; save stack frame
|
||||
mov si,2[bp] ; SI -> parameter block
|
||||
mov ax,1
|
||||
push ax ; read 1 byte ahead
|
||||
push ds ; use fdos_pb as read-ahead
|
||||
lea ax,6[si] ; buffer
|
||||
push ax
|
||||
push ds:word ptr 2[si] ; user file number
|
||||
mov ax,MS_X_READ ; READ function #, so we create
|
||||
push ax ; a dummy fdos_pb
|
||||
mov bx,sp ; SS:BX -> dummy fdos_pb
|
||||
mov cx,offset ioctl6_20 ; CX -> return address
|
||||
push cx ; Return to here
|
||||
push ss ; save parameter segment
|
||||
push bx ; save parameter offset
|
||||
push ax ; save sub-function
|
||||
mov bp,sp ; SS:BP -> working variables
|
||||
call fdos_read ; make FDOS_READ do the hard word
|
||||
add sp,4*WORD ; discard param's on stack
|
||||
ioctl6_20:
|
||||
add sp,4*WORD ; discard most of dummy fdos_pb
|
||||
pop cx ; return # read
|
||||
cmp bx,ED_LASTERROR ; did we succeed ?
|
||||
jb ioctl6_30 ; if so we can trust # read
|
||||
xor cx,cx ; else in error assume nothing
|
||||
ioctl6_30:
|
||||
pop bp ; recover stack frame
|
||||
pop bx ; rewind DHNDL_POS to where
|
||||
pop es
|
||||
pop es:DHNDL_POSHI[bx] ; it was before we started
|
||||
pop es:DHNDL_POSLO[bx]
|
||||
mov ax,1a00h ; assume not ready
|
||||
jcxz ioctl6_40
|
||||
dec ax ; AL = FF, ie. ready
|
||||
mov si,2[bp] ; SI -> parameter block
|
||||
mov ah,ds:byte ptr 6[si] ; get character we read
|
||||
ioctl6_40:
|
||||
jmp device_OK
|
||||
|
||||
|
||||
ioctl7: ; file output status
|
||||
;------
|
||||
call vfy_dhndl_ptr ; make sure this is an open handle
|
||||
mov ax,0FFh ; assume it's networked/disk
|
||||
mov dx,es:DHNDL_WATTR[bx]
|
||||
test dx,DHAT_REMOTE
|
||||
jnz ioctl6_40 ; networked handles are always ready
|
||||
test dx,DHAT_DEV
|
||||
jz ioctl6_40 ; files are always ready
|
||||
jmp ioc7_dev ; devices we ask...
|
||||
|
||||
|
||||
|
||||
ioctl9: ; networked drive check
|
||||
;------
|
||||
call local_disk ; get disk semaphore
|
||||
call get_pb2_drive ; get specified drive
|
||||
call get_ldt ; ES:BX -> LDT for this drive
|
||||
jc ioctl940
|
||||
mov ax,es:LDT_FLAGS[bx]
|
||||
test ah,LFLG_NETWRKD/256
|
||||
jz ioctl910
|
||||
if 1
|
||||
mov ax,1000h ; return drive as remote
|
||||
else
|
||||
les di,es:LDT_PDT[bx] ; pick up network internal pointer
|
||||
mov ax,es:4[di] ; pick up garbage
|
||||
or ah,10h ; return drive as remote
|
||||
endif
|
||||
jmps ioctl930
|
||||
|
||||
ioctl910:
|
||||
test ah,LFLG_PHYSICAL/256
|
||||
jz ioctl940
|
||||
test ah,LFLG_SUBST/256
|
||||
xchg ax,dx ; save flags
|
||||
mov ax,8000h ; assume it's SUBST'd
|
||||
jnz ioctl920
|
||||
test dh,LFLG_JOINED/256
|
||||
xchg al,ah ; assume it's JOIN'd
|
||||
jnz ioctl930
|
||||
xor ax,ax ; clear if not
|
||||
ioctl920:
|
||||
push ax
|
||||
call get_pb2_ddsc ; get drives DDSC_
|
||||
pop ax
|
||||
les si,es:DDSC_DEVHEAD[bx] ; ES:SI -> device driver
|
||||
or ax,es:4[si] ; get device attributes
|
||||
ioctl930:
|
||||
mov fdos_pb+6,ax ; return updated status
|
||||
ret
|
||||
|
||||
ioctl940:
|
||||
jmp fdos_ED_DRIVE ; return ED_DRIVE error
|
||||
|
||||
|
||||
ioctlA: ; networked handle check
|
||||
;------
|
||||
call vfy_dhndl_ptr
|
||||
mov ax,es:DHNDL_WATTR[bx]
|
||||
jmp device_OK ; return attributes
|
||||
|
||||
|
||||
ioctlE:
|
||||
;------
|
||||
call local_disk
|
||||
mov al,CMD_GET_DEVICE ; get logical device
|
||||
jmps iocEFcommon ; common code for IOCTL(E)/IOCTL(F)
|
||||
|
||||
ioctlF:
|
||||
;------
|
||||
call local_disk
|
||||
mov al,CMD_SET_DEVICE ; set logical device
|
||||
iocEFcommon:
|
||||
mov req_hdr,RH24_LEN
|
||||
mov req_hdr+2,al
|
||||
call get_pb2_ddsc ; get drives DDSC_
|
||||
inc ax ; make drive one-relative
|
||||
mov req_hdr+13,al ; set this as new drive
|
||||
xor ax,ax ; assume not supported
|
||||
push ds
|
||||
lds si,es:DDSC_DEVHEAD[bx] ; does device driver support function ?
|
||||
test ds:DH_ATTRIB[si],DA_GETSET
|
||||
pop ds
|
||||
jz iocF_single ; skip if not supported
|
||||
call block_device_driver ; call the device driver
|
||||
call fdos_error_check ; return any errors
|
||||
mov al,req_hdr+1 ; get returned drive
|
||||
iocF_single: ; AX = return value
|
||||
mov ah,7
|
||||
mov fdos_pb+6,ax ; return the drive
|
||||
ret
|
||||
|
||||
if PASSWORD
|
||||
|
||||
ioctl54: ; set global password
|
||||
;-------
|
||||
call local_disk ; get the MX disk
|
||||
push ds
|
||||
lds si,dword ptr ioctlRH+14
|
||||
call hash_pwd ; encrypt new default password
|
||||
pop ds
|
||||
mov global_password,ax
|
||||
ret
|
||||
|
||||
endif
|
||||
|
||||
end
|
Reference in New Issue
Block a user