From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/DOS/IOCTL.ASM | 745 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 745 insertions(+) create mode 100644 v4.0/src/DOS/IOCTL.ASM (limited to 'v4.0/src/DOS/IOCTL.ASM') diff --git a/v4.0/src/DOS/IOCTL.ASM b/v4.0/src/DOS/IOCTL.ASM new file mode 100644 index 0000000..8007244 --- /dev/null +++ b/v4.0/src/DOS/IOCTL.ASM @@ -0,0 +1,745 @@ +; SCCSID = @(#)IOCTL.INC 1.15 85/09/05 +TITLE IOCTL - IOCTL system call +NAME IOCTL + +; +; +; IOCTL system call. +; +; +; $IOCTL +; +; Revision history: +; +; Created: ARR 4 April 1983 +; +; GenericIOCTL added: KGS 22 April 1985 +; +; A000 version 4.00 Jan. 1988 + + + +.xlist +; +; get the appropriate segment definitions +; +include dosseg.asm + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME SS:DOSGROUP,CS:DOSGROUP + +.xcref +INCLUDE DOSSYM.INC +INCLUDE DEVSYM.INC +include ioctl.inc +include ifssym.inc ;AN000; +.cref +.list + + i_need THISCDS,DWORD + i_need IOCALL,BYTE + i_need IOMED,BYTE + i_need IOSCNT,WORD + i_need IOXAD,DWORD + I_need RetryCount,WORD + I_need RetryLoop,WORD + I_need EXTERR_LOCUS,BYTE + I_need OPENBUF,BYTE + I_need ExtErr,WORD + I_need DrvErr,BYTE + I_need USER_IN_AX,WORD ;AN000; + I_need Temp_Var2,WORD ;AN000; + +BREAK + +; +; Assembler usage: +; MOV BX, Handle +; MOV DX, Data +; +; (or LDS DX,BUF +; MOV CX,COUNT) +; +; MOV AH, Ioctl +; MOV AL, Request +; INT 21h +; +; AH = 0 Return a combination of low byte of sf_flags and device driver +; attribute word in DX, handle in BX: +; DH = high word of device driver attributes +; DL = low byte of sf_flags +; 1 Set the bits contained in DX to sf_flags. DH MUST be 0. Handle +; in BX. +; 2 Read CX bytes from the device control channel for handle in BX +; into DS:DX. Return number read in AX. +; 3 Write CX bytes to the device control channel for handle in BX from +; DS:DX. Return bytes written in AX. +; 4 Read CX bytes from the device control channel for drive in BX +; into DS:DX. Return number read in AX. +; 5 Write CX bytes to the device control channel for drive in BX from +; DS:DX. Return bytes written in AX. +; 6 Return input status of handle in BX. If a read will go to the +; device, AL = 0FFh, otherwise 0. +; 7 Return output status of handle in BX. If a write will go to the +; device, AL = 0FFh, otherwise 0. +; 8 Given a drive in BX, return 1 if the device contains non- +; removable media, 0 otherwise. +; 9 Return the contents of the device attribute word in DX for the +; drive in BX. 0200h is the bit for shared. 1000h is the bit for +; network. 8000h is the bit for local use. +; A Return 8000h if the handle in BX is for the network or not. +; B Change the retry delay and the retry count for the system. BX is +; the count and CX is the delay. +; +; Error returns: +; AX = error_invalid_handle +; = error_invalid_function +; = error_invalid_data +; +;------------------------------------------------------------------------------- +; +; This is the documentation copied from DOS 4.0 it is much better +; than the above +; +; There are several basic forms of IOCTL calls: +; +; +; ** Get/Set device information: ** +; +; ENTRY (AL) = function code +; 0 - Get device information +; 1 - Set device information +; (BX) = file handle +; (DX) = info for "Set Device Information" +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; (DX) = info for "Get Device Information" +; USES ALL +; +; +; ** Read/Write Control Data From/To Handle ** +; +; ENTRY (AL) = function code +; 2 - Read device control info +; 3 - Write device control info +; (BX) = file handle +; (CX) = transfer count +; (DS:DX) = address for data +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; (AX) = count of bytes transfered +; USES ALL +; +; +; ** Read/Write Control Data From/To Block Device ** +; +; ENTRY (AL) = function code +; 4 - Read device control info +; 5 - Write device control info +; (BL) = Drive number (0=default, 1='A', 2='B', etc) +; (CX) = transfer count +; (DS:DX) = address for data +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; (AX) = count of bytes transfered +; USES ALL +; +; +; ** Get Input/Output Status ** +; +; ENTRY (AL) = function code +; 6 - Get Input status +; 7 - Get Output Status +; (BX) = file handle +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; (AL) = 00 if not ready +; (AL) = FF if ready +; USES ALL +; +; +; ** Get Drive Information ** +; +; ENTRY (AL) = function code +; 8 - Check for removable media +; 9 - Get device attributes +; (BL) = Drive number (0=default, 1='A', 2='B', etc) +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; (AX) = 0/1 media is removable/fixed (func. 8) +; (DX) = device attribute word (func. 9) +; USES ALL +; +; +; ** Get Redirected bit ** +; +; ENTRY (AL) = function code +; 0Ah - Network stuff +; (BX) = file handle +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; (DX) = SFT flags word, 8000h set if network file +; USES ALL +; +; +; ** Change sharer retry parameters ** +; +; ENTRY (AL) = function code +; 0Bh - Set retry parameters +; (CX) = retry loop count +; (DX) = number of retries +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; USES ALL +; +; +; ================================================================= +; +; ** New Standard Control ** +; +; ALL NEW IOCTL FACILITIES SHOULD USE THIS FORM. THE OTHER +; FORMS ARE OBSOLETE. +; +; ================================================================= +; +; ENTRY (AL) = function code +; 0Ch - Control Function subcode +; (BX) = File Handle +; (CH) = Category Indicator +; (CL) = Function within category +; (DS:DX) = address for data, if any +; (SI) = Passed to device as argument, use depends upon function +; (DI) = Passed to device as argument, use depends upon function +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; (SI) = Return value, meaning is function dependent +; (DI) = Return value, meaning is function dependent +; (DS:DX) = Return address, use is function dependent +; USES ALL +; +; ============== Generic IOCTL Definitions for DOS 3.2 ============ +; (See dos/ioctl.mac for more info) +; +; ENTRY (AL) = function code +; 0Dh - Control Function subcode +; (BL) = Drive Number (0 = Default, 1= 'A') +; (CH) = Category Indicator +; (CL) = Function within category +; (DS:DX) = address for data, if any +; (SI) = Passed to device as argument, use depends upon function +; (DI) = Passed to device as argument, use depends upon function +; +; EXIT 'C' set if error +; (AX) = error code +; 'C' clear if OK +; (DS:DX) = Return address, use is function dependent +; USES ALL +; + + procedure $IOCTL,NEAR + ASSUME DS:NOTHING,ES:NOTHING + MOV SI,DS ; Stash DS for calls 2,3,4 and 5 + context DS + CMP AL,3 + JBE ioctl_check_char ; char device + JMP ioctl_check_block ; Block device +ioctl_check_char: + invoke SFFromHandle ; ES:DI -> SFT + JNC ioctl_check_permissions ; have valid handle +ioctl_bad_handle: + error error_invalid_handle + +ioctl_check_permissions: + CMP AL,2 + JAE ioctl_control_string + CMP AL,0 + MOV AL,BYTE PTR ES:[DI.sf_flags]; Get low byte of flags + JZ ioctl_read ; read the byte + PUSH DX ;AN000;MS. + AND DH,0FEH ;AN000;MS.allow DH=01H + POP DX ;AN000;MS. + JZ ioctl_check_device ; can I set with this data? + error error_invalid_data ; no DH <> 0 + +ioctl_bad_funj2: + JMP ioctl_bad_fun + +ioctl_check_device: + TEST AL,devid_device ; can I set this handle? + JZ do_exception ; no, it is a file. + OR DL,devid_device ; Make sure user doesn't turn off the + ; device bit!! He can muck with the + ; others at will. + MOV [EXTERR_LOCUS],errLOC_SerDev + MOV BYTE PTR ES:[DI.sf_flags],DL ;AC000;MS.; Set flags +do_exception: + OR BYTE PTR ES:[DI.sf_flags+1],DH;AN000;MS.;set 100H bit for disk full + + transfer SYS_RET_OK + + + + + +ioctl_read: + MOV [EXTERR_LOCUS],errLOC_Disk + XOR AH,AH + TEST AL,devid_device ; Should I set high byte + JZ ioctl_no_high ; no + MOV [EXTERR_LOCUS],errLOC_SerDev + LES DI,ES:[DI.sf_devptr] ; Get device pointer + MOV AH,BYTE PTR ES:[DI.SDEVATT+1] ; Get high byte +ioctl_no_high: + MOV DX,AX + invoke get_user_stack + MOV [SI.user_DX],DX + transfer SYS_RET_OK + +ioctl_control_string: + TEST ES:[DI.sf_flags],devid_device ; can I? + JNZ ioctl_ctl_str_1 + JMP ioctl_bad_fun ; No it is a file +ioctl_ctl_str_1: + TEST ES:[DI.sf_flags],sf_isnet ;AN000;IFS.; IFS ? + JZ localrw ;AN000;IFS.; no + JMP callifs ;AN000;IFS.; call IFS +localrw: + MOV [EXTERR_LOCUS],errLOC_SerDev + LES DI,ES:[DI.sf_devptr] ; Get device pointer + XOR BL,BL ; Unit number of char dev = 0 + JMP ioctl_do_string + +ioctl_get_devj: + JMP ioctl_get_dev + +ioctl_check_block: + DEC AL + DEC AL ; 4=2,5=3,6=4,7=5,8=6,9=7,10=8,11=9 + CMP AL,3 + JBE ioctl_get_devj + CMP AL,6 + JAE ioctl_rem_media_check + + MOV AH,1 + SUB AL,4 ; 6=0,7=1 + JZ ioctl_get_status + MOV AH,3 +ioctl_get_status: + PUSH AX + invoke GET_IO_SFT + POP AX + JNC DO_IOFUNC + JMP ioctl_bad_handle ; invalid SFT + +DO_IOFUNC: + invoke IOFUNC + MOV AH,AL + MOV AL,0FFH + JNZ ioctl_status_ret + INC AL +ioctl_status_ret: + transfer SYS_RET_OK + +ioctl_rem_media_check: ; 4=2,5=3,6=4,7=5,8=6,9=7,10=8,11=9 + JE ioctl_rem_mediaj + + SUB AL,7 ; 9=0,10=1,11=2,12=3,13=4,14=5,15=6 + JNZ Rem_med_chk_1 + JMP Ioctl_Drive_attr + +ioctl_rem_mediaj: + jmp ioctl_rem_media + +ioctl_bad_funj4: + jmp ioctl_bad_fun + +Rem_med_chk_1: + + DEC AL ; 10=0,11=1,12=2,13=3,14=4,15=5 + jnz Set_Retry_chk + Jmp Ioctl_Handle_redirj + +Set_Retry_chk: + DEC AL ; 11=0,12=1,13=2,14=3,15=4 + JZ Set_Retry_Parameters + + DEC AL ; 12=0,13=1,14=2,15=3 + JZ GENERICIOCTLHANDLE + + DEC AL ; 13=0,14=1,15=2 + JZ GENERICIOCTL + + CMP AL,2 + JA ioctl_bad_funj4 + JMP ioctl_drive_owner +Set_Retry_Parameters: + MOV RetryLoop,CX ; 0 retry loop count allowed + OR DX,DX ; zero retries not allowed + JNZ goodtr + JMP IoCtl_Bad_Fun +goodtr: + MOV RetryCount,DX ; Set new retry count +doneok: + transfer Sys_Ret_Ok ; Done + +; Generic IOCTL entry point. +; here we invoke the Generic IOCTL using the IOCTL_Req structure. +; SI:DX -> Users Device Parameter Table +; IOCALL -> IOCTL_Req structure +GENERICIOCTLHANDLE: + invoke SFFromHandle ; Get SFT for device. + jnc goodh + JMP ioctl_bad_handlej +goodh: +; test word ptr [DI.sf_flags],sf_isnet + CALL TEST_IFS_REMOTE ;AN000;;IFS. test if remote + JZ okokok ;AN000;;IFS. + jmp ioctl_bad_fun ; Cannot do this over net. +okokok: + TEST [DI.sf_flags],sf_isnet ;AN000;IFS.; local IFS + JNZ callifs ;AN000;IFS.; yes + + + mov [EXTERR_LOCUS],ErrLOC_Serdev + les di,es:[di.sf_devptr] ; Get pointer to device. + jmp short Do_GenIOCTL + +GENERICIOCTL: + mov [EXTERR_LOCUS],ErrLOC_Disk + cmp ch,IOC_DC ; Only disk devices are allowed to use + jne ioctl_bad_fun ; no handles with Generic IOCTL. + CALL Check_If_Net ; ES:DI := Get_hdr_block of device in BL + JNZ ioctl_bad_fun ; There are no "net devices", and they + PUSH ES ; certainly don't know how to do this ;AN000; + PUSH DI ;AN000;IFS. + LES DI,[THISCDS] ;AN000;IFS. ; + TEST ES:[DI.curdir_flags],curdir_isnet;AN000;IFS. ; local IFS ? + POP DI ;AN000;IFS. + POP ES ;AN000;IFS. + JZ Do_GenIOCTL ;AN000;IFS. ; no +callifs: + CMP byte ptr [User_In_AX+1],69H ;AN000; ;IFS. + JNZ is44xx ;AN000; ;IFS. + MOV AX,440DH ;AN000; ;IFS. + PUSH AX ;AN000; ;IFS. + JMP SHORT callrose ;AN000; ;IFS. +is44xx: + PUSH [User_In_AX] ;AN000; ;IFS. call IFSFUNC +callrose: + MOV DS,SI ;AN000; ;IFS. + MOV AX,(multNET SHL 8) or 43 ;AN000; ;IFS. + INT 2FH ;AN000; ;IFS. + POP BX ;AN000; ;IFS. + JNC doneok ;AN000; ;IFS. + MOV DI,AX ;AN000; ;IFS. + JMP device_err ;AN000; ;IFS. +Do_GenIOCTL: + test ES:[DI.SDEVATT],DEV320 ; Can device handle Generic IOCTL funcs + jz ioctl_bad_fun + PUSH ES ; DEVIOCALL2 expects Device header block + PUSH DI ; in DS:SI + ;set up Generic IOCTL Request Block + MOV byte ptr IOCALL.ReqLen,(size IOCTL_Req) + MOV byte ptr IOCALL.ReqFunc,GENIOCTL + MOV byte ptr IOCALL.ReqUnit,BL + MOV byte ptr IOCALL.MajorFunction,CH + MOV byte ptr IOCALL.MinorFunction,CL + MOV word ptr IOCALL.Reg_SI,SI + MOV word ptr IOCALL.Reg_DI,DI + MOV word ptr IOCALL.GenericIOCTL_Packet,DX + MOV word ptr IOCALL.GenericIOCTL_Packet + 2,SI + + MOV BX,offset DOSGROUP:IOCALL + + PUSH SS + POP ES + +ASSUME DS:NOTHING ; DS:SI -> Device header. + POP SI + POP DS + jmp ioctl_do_IO ; Perform Call to device driver + +IOCtl_Handle_RedirJ: + JMP IOCTL_Handle_Redir +ioctl_bad_fun: + error error_invalid_function + +ioctl_bad_handlej: + jmp ioctl_bad_handle + +; Function 8 +ioctl_rem_media: + CALL Check_If_Net + JNZ ioctl_bad_fun ; There are no "net devices", and they + ; certainly don't know how to do this + ; call. + TEST ES:[DI.SDEVATT],DEVOPCL ; See if device can + JZ ioctl_bad_fun ; NO + MOV [IOCALL.REQFUNC],DEVRMD + MOV AL,REMHL + MOV AH,BL ; Unit number + MOV WORD PTR [IOCALL.REQLEN],AX + XOR AX,AX + MOV [IOCALL.REQSTAT],AX + PUSH ES + POP DS +ASSUME DS:NOTHING + MOV SI,DI ; DS:SI -> driver + PUSH SS + POP ES + MOV BX,OFFSET DOSGROUP:IOCALL ; ES:BX -> Call header + SaveReg + invoke DEVIOCALL2 + RestoreReg + MOV AX,[IOCALL.REQSTAT] ; Get Status word + AND AX,STBUI ; Mask to busy bit + MOV CL,9 + SHR AX,CL ; Busy bit to bit 0 + transfer SYS_RET_OK + +; Function 9 +Ioctl_Drive_attr: + +;;;;; MOV AL,BL ;AC000;; Drive +;;;;; invoke GETTHISDRV ;AC000; +;;;;; ;AC000; +;;;;; JC ioctl_drv_err ; drive not valid + call Get_Driver_BL + JC ioctl_drv_err ; drive not valid + MOV AX,[Temp_Var2] ;AN000;IFS. + mov dx,word ptr es:[di.SDEVATT] ; get device attribute word + MOV BL,AL ; Phys letter to BL (A=0) + LES DI,[THISCDS] +;;;;; TEST ES:[DI.curdir_flags],curdir_isnet + CALL TEST_IFS_REMOTE2 ;AN000;IFS. test if remote + JZ IOCTLShare + OR DX,1000h +IOCTLShare: + Context DS +ASSUME DS:NOTHING + MOV SI,OFFSET DOSGROUP:OPENBUF + ADD BL,"A" + MOV [SI],BL + MOV WORD PTR [SI+1],003AH ; ":",0 + MOV AX,0300H + CLC + INT int_IBM + JNC ioctlLocal ; Not shared + OR DX,0200H ; Shared, bit 9 +IOCTLLocal: + TEST ES:[DI].curdir_flags,curdir_local + JZ ioctl_set_dx + OR DX,8000h + +ioctl_set_DX: + invoke get_user_stack + MOV [SI.user_DX],DX + transfer SYS_RET_OK + +ioctl_drv_err: + MOV AL,[DrvErr] ;AN000;IFS. DrvErr is saved in GetThisDrv + transfer SYS_RET_ERR ;AN000;IFS. + +; Function 10 +Ioctl_Handle_redir: + invoke SFFromHandle ; ES:DI -> SFT + JNC ioctl_got_sft ; have valid handle + error error_invalid_handle + +ioctl_got_sft: + MOV DX,ES:[DI.sf_flags] ; Get flags + JMP ioctl_set_DX + +ioctl_bad_funj: + JMP ioctl_bad_fun + +ioctl_get_dev: + DOSAssume CS,,"IOCTL/IOCtl_Get_Dev" + CALL Check_If_Net + JNZ ioctl_bad_funj ; There are no "net devices", and they + ; certainly don't know how to do this + ; call. +ioctl_do_string: + TEST ES:[DI.SDEVATT],DEVIOCTL; See if device accepts control + JZ ioctl_bad_funj ; NO + DEC AL + DEC AL + JZ ioctl_control_read + MOV [IOCALL.REQFUNC],DEVWRIOCTL + JMP SHORT ioctl_control_call +ioctl_control_read: + MOV [IOCALL.REQFUNC],DEVRDIOCTL +ioctl_control_call: + MOV AL,DRDWRHL +ioctl_setup_pkt: + MOV AH,BL ; Unit number + MOV WORD PTR [IOCALL.REQLEN],AX + XOR AX,AX + MOV [IOCALL.REQSTAT],AX + MOV [IOMED],AL + MOV [IOSCNT],CX + MOV WORD PTR [IOXAD],DX + MOV WORD PTR [IOXAD+2],SI + PUSH ES + POP DS +ASSUME DS:NOTHING + MOV SI,DI ; DS:SI -> driver + PUSH SS + POP ES + MOV BX,OFFSET DOSGROUP:IOCALL ; ES:BX -> Call header +ioctl_do_IO: + invoke DEVIOCALL2 + TEST [IOCALL.REQSTAT],STERR ;Error? + JNZ Ioctl_string_err + MOV AX,[IOSCNT] ; Get actual bytes transferred + transfer SYS_RET_OK + +Ioctl_string_err: + MOV DI,[IOCALL.REQSTAT] ;Get Error +device_err: + AND DI,STECODE ; mask out irrelevant bits + MOV AX,DI + invoke SET_I24_EXTENDED_ERROR + mov ax, cs:extErr + transfer SYS_RET_ERR + +Get_Driver_BL: + DOSAssume CS,,"Get_Driver_BL" + ASSUME ES:NOTHING +; BL is drive number (0=default) +; Returns pointer to device in ES:DI, unit number in BL if carry clear +; No regs modified + + PUSH AX + MOV AL,BL ; Drive + invoke GETTHISDRV + JNC ioctl_goodrv ;AC000;IFS. + CMP AL,error_not_dos_disk ;AN000;IFS. if unknow media then + JZ ioctl_goodrv ;AN000;IFS. let it go + STC ;AN000;IFS. else + JMP SHORT ioctl_bad_drv ;AN000;IFS. error +ioctl_goodrv: + XOR BL,BL ; Unit zero on Net device + MOV [EXTERR_LOCUS],errLOC_Net + LES DI,[THISCDS] +; TEST ES:[DI.curdir_flags],curdir_isnet + CALL TEST_IFS_REMOTE2 ;AN000;;IFS. test if remote + LES DI,ES:[DI.curdir_devptr]; ES:DI -> Dpb or net dev + JNZ got_dev_ptr ; Is net + MOV [EXTERR_LOCUS],errLOC_Disk + MOV BL,ES:[DI.dpb_UNIT] ; Unit number + LES DI,ES:[DI.dpb_driver_addr] ; Driver addr +got_dev_ptr: + CLC + MOV [Temp_Var2],AX ;AN000;IFS. +ioctl_bad_drv: + POP AX + return + +; +; Checks if the device is over the net or not. Returns result in ZERO flag. +; If no device is found, the return address is popped off the stack, and a +; jump is made to ioctl_drv_err. +; +; On Entry: +; Registers same as those for Get_Driver_BL +; +; On Exit: +; ZERO flag - set if not a net device +; - reset if net device +; ES:DI -> the device +; +Check_If_Net: + CALL Get_Driver_BL + JC ioctl_drv_err_pop ; invalid drive letter +entry TEST_IFS_REMOTE2 + PUSH ES + PUSH DI + LES DI,[THISCDS] + TEST ES:[DI.curdir_flags],curdir_isnet + JZ belocal ;AN000; ;IFS. + LES DI,ES:[DI.curdir_ifs_hdr] ;AN000; ;IFS. test if remote +TEST_REMOTE: ;AN000; + TEST ES:[DI.ifs_attribute],IFSREMOTE;AN000; ;IFS. +belocal: + POP DI + POP ES + ret + +ioctl_drv_err_pop: + pop ax ; pop off return address + jmp ioctl_drv_err + +ioctl_bad_funj3: + jmp ioctl_bad_fun + +ioctl_string_errj: + jmp ioctl_string_err + +; Functions 14 and 15 +ioctl_drive_owner: + Call Check_If_Net + JNZ ioctl_bad_funj3 ; There are no "net devices", and they + ; certainly don't know how to do this + ; call. + TEST ES:[DI.SDEVATT],DEV320 ; See if device can handle this + JZ ioctl_bad_funj3 ; NO + dec al + jz GetOwner + MOV [IOCALL.REQFUNC],DEVSETOWN + jmp short ioctl_do_own +GetOwner: + MOV [IOCALL.REQFUNC],DEVGETOWN +ioctl_do_own: + MOV AL,OWNHL + MOV AH,BL ; Unit number + MOV WORD PTR [IOCALL.REQLEN],AX + XOR AX,AX + MOV [IOCALL.REQSTAT],AX + PUSH ES + POP DS +ASSUME DS:NOTHING + MOV SI,DI ; DS:SI -> driver + PUSH SS + POP ES + MOV BX,OFFSET DOSGROUP:IOCALL ; ES:BX -> Call header + SaveReg + invoke DEVIOCALL2 + RestoreReg + test [IOCALL.REQSTAT],STERR + jnz ioctl_string_errj + MOV AL,BYTE PTR [IOCALL.REQUNIT] ; Get owner returned by device + ; owner returned is 1-based. + transfer SYS_RET_OK + +EndProc $IOCTL + + +;Input: ES:DI -> SFT +;Functions: test if a remote file +;Output: Z flag set, local file +; + + procedure TEST_IFS_REMOTE,NEAR ;AN000; + ASSUME DS:NOTHING,ES:NOTHING ;AN000; + + TEST ES:[DI.sf_flags],sf_isnet ;AN000;;IFS. ifs ? + JZ nonifs ;AN000;;IFS. no + PUSH ES ;AN000;;IFS. save regs + PUSH DI ;AN000;;IFS. + LES DI,ES:[DI.sf_IFS_hdr] ;AN000;;IFS. get ifs header + JMP TEST_REMOTE ;AN000;;IFS. +nonifs: ;AN000; + return ;AN000;;IFS. +EndProc TEST_IFS_REMOTE ;AN000; + +CODE ENDS +END -- cgit v1.2.3