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/FILE.ASM | 909 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 909 insertions(+) create mode 100644 v4.0/src/DOS/FILE.ASM (limited to 'v4.0/src/DOS/FILE.ASM') diff --git a/v4.0/src/DOS/FILE.ASM b/v4.0/src/DOS/FILE.ASM new file mode 100644 index 0000000..9fca034 --- /dev/null +++ b/v4.0/src/DOS/FILE.ASM @@ -0,0 +1,909 @@ +; SCCSID = @(#)file.asm 1.2 85/07/23 +; SCCSID = @(#)file.asm 1.2 85/07/23 +TITLE FILE - Pathname related system calls +NAME FILE + +; +; Pathname related system calls. These will be passed direct text of the +; pathname from the user. They will need to be passed through the macro +; expander prior to being sent through the low-level stuff. I/O specs are +; defined in DISPATCH. The system calls are: +; +; $Open written +; $Creat written +; $ChMod written +; $Unlink written +; $Rename written +; $CreateTempFile written +; $CreateNewFile written +; $Extended_Open written DOS 4.00 +; GetIOParms written DOS 4.00 +; +; Revision history: +; +; Created: MZ 4 April 1983 +; 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 fastopen.inc +include EA.inc ;AN000; +include version.inc +.cref +.list +.sall + + EXTRN DOS_OPEN:NEAR,DOS_CREATE:NEAR,DOS_Create_New:NEAR + +IF NOT IBMCOPYRIGHT + extrn Set_EXT_mode:near +ENDIF + + I_need WFP_Start,WORD ; pointer to beginning of expansion + I_Need ThisCDS,DWORD ; pointer to curdir in use + I_need ThisSft,DWORD ; SFT pointer for DOS_Open + I_need pJFN,DWORD ; temporary spot for pointer to JFN + I_need JFN,WORD ; word JFN for process + I_need SFN,WORD ; word SFN for process + I_Need OpenBuf,128 ; buffer for filename + I_Need RenBuf,128 ; buffer for filename in rename + I_need Sattrib,BYTE ; byte attribute to search for + I_need Ren_WFP,WORD ; pointer to real path + I_need cMeta,BYTE + I_need EXTERR,WORD ; extended error code + I_need EXTERR_LOCUS,BYTE ; Extended Error Locus + i_need JShare,DWORD ; share jump table + I_need fSharing,BYTE ; TRUE => via ServerDOSCall + I_need FastOpenTable,BYTE + I_need CPSWFLAG,BYTE ;AN000;FT. cpsw falg + I_need EXTOPEN_FLAG,WORD ;AN000;FT. extended file open flag + I_need EXTOPEN_ON,BYTE ;AN000;FT. extended open flag + I_need EXTOPEN_IO_MODE,WORD ;AN000;FT. IO mode + I_need XA_from,BYTE ;AN000;;FT. for get/set XA + I_need SAVE_ES,WORD ;AN000;;FT. for get/set XA + I_need SAVE_DI,WORD ;AN000;;FT. for get/set XA + I_need SAVE_DS,WORD ;AN000;;FT. for get/set XA + I_need SAVE_SI,WORD ;AN000;;FT. for get/set XA + I_need SAVE_DX,WORD ;AN000;;FT. for get/set XA + I_need SAVE_BX,WORD ;AN000;;FT. for get/set XA + I_need SAVE_CX,WORD ;AN000;;FT. for get/set XA + I_need NO_FILTER_DPATH,DWORD ;AN000;; pointer to original path of dest + I_need Temp_Var,WORD ;AN000;; + I_need DOS34_FLAG,WORD ;AN000;; + I_need Temp_Var2,WORD ;AN000;; +if debug + I_need BugLev,WORD + I_need BugTyp,WORD +include bugtyp.asm +endif + +BREAK <$Open - open a file from a path string> + +; +; $Open - given a path name in DS:DX and an open mode in AL, access the file +; and return a handle +; Inputs: DS:DX - pointer to asciz name +; AL - open mode +; Outputs: Carry Set - AX has error code for invalid open +; Carry Clear - AX has per process handle number +; Registers modified: most + +Procedure $Open,NEAR + ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup + fmt TypSysCall,LevLog,<"Open\n"> + fmt TypSysCall,LevArgs,<" Mode = $x file = '$S'\n">, + XOR AH,AH +Entry $Open2 ;AN000; + mov ch,attr_hidden+attr_system+attr_directory + call SetAttrib + MOV CX,OFFSET DOSGroup:DOS_Open ; address of routine to call + SaveReg ; Save mode on stack +IF DBCS ;AN000; + MOV [Temp_Var],0 ;AN000;KK. set variable with 0 +ENDIF ;AN000; + +AccessFile: +; +; Grab a free SFT. +; +IF DBCS ;AN000; + TEST [Temp_Var],8 ;AN000;;KK. volume id bit set ;AN000; + JZ novol ;AN000;;KK. no ;AN000; + OR [DOS34_FLAG],DBCS_VOLID ;AN000;;KK. set bit for transpath ;AN000; +novol: ;AN000; +ENDIF ;AN000; + EnterCrit critSFT + invoke SFNFree ; get a free sfn + LeaveCrit critSFT + JC OpenFailJ ; oops, no free sft's + MOV SFN,BX ; save the SFN for later + fmt TypAccess,LevSFN,<"AccessFile setting SFN to $x\n">, + MOV WORD PTR [ThisSFT],DI ; save the SF offset + MOV WORD PTR [ThisSFT+2],ES ; save the SF segment +; +; Find a free area in the user's JFN table. +; + invoke JFNFree ; get a free jfn + JNC SaveJFN +OpenFailJ: + JMP OpenFail ; there were free JFNs... try SFN +SaveJFN: + MOV WORD PTR [pJFN],DI ; save the jfn offset + MOV WORD PTR [pJFN+2],ES ; save the jfn segment + MOV [JFN],BX ; save the jfn itself +; +; We have been given an JFN. We lock it down to prevent other tasks from +; reusing the same JFN. +; + MOV BX,SFN + MOV ES:[DI],BL ; assign the JFN + MOV SI,DX ; get name in appropriate place + MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer + SaveReg ; save routine to call + invoke TransPath ; convert the path + RestoreReg ; restore routine to call + LDS SI,ThisSFT + ASSUME DS:NOTHING + JC OpenCleanJ ; no error, go and open file + CMP cMeta,-1 + JZ SetSearch + MOV AL,error_file_not_found ; no meta chars allowed +OpenCleanJ: + JMP OpenClean +SetSearch: + RestoreReg ; Mode (Open), Attributes (Create) +; +; We need to get the new inheritance bits. +; + xor cx,cx + CMP BX,OFFSET DOSGroup:DOS_OPEN + JNZ DoOper + TEST AL,sharing_no_inherit ; look for no inher + JZ DoOper + AND AL,07Fh ; mask off inherit bit + MOV CX,sf_no_inherit +DoOper: + MOV [SI].sf_mode,0 ; initialize mode field to 0 + MOV [SI.SF_mft],0 ; clean out sharing info +; +;------------------------------------------------------------HKN 8/7/88 +; Check if this is an extended open. If so you must set the +; modes in sf_mode. Call Set_EXT_mode to do all this. See +; Set_EXT_mode in creat.asm +; +IF NOT IBMCOPYRIGHT + + push es ; set up es:di to point to SFT + push di + push ds + pop es + push si + pop di + call Set_EXT_mode + pop di + pop es + +ENDIF + +;----------------------------------------------------------------------- + + Context DS + SaveReg + CALL BX ; blam! + RestoreReg + LDS SI,ThisSFT + ASSUME DS:NOTHING + JC OpenE2 ;AN000;FT. chek extended open hooks first +; +; The SFT was successfully opened. Remove busy mark. +; +OpenOK: + ASSUME DS:NOTHING +; MOV AL,[SI].sf_attr_hi ;AN000;FT. save file type for EXEC +; MOV BYTE PTR [Temp_Var2],AL ;AN000;FT. + MOV [SI].sf_ref_count,1 + OR [SI].sf_flags,CX ; set no inherit bit if necessary +; +; If the open mode is 70, we scan the system for other SFT's with the same +; contents. If we find one, then we can 'collapse' thissft onto the already +; opened one. Otherwise we use this new one. We compare uid/pid/mode/mft +; +; Since this is only relevant on sharer systems, we stick this code into the +; sharer. +; + MOV AX,JFN +if installed + Call JShare + 12 * 4 +else + Call ShCol +endif + fmt TypAccess,LevSFN,<"AccessFile setting SFN to -1\n"> + MOV SFN,-1 ; clear out sfn pointer + fmt TypSysCall,LevLog,<"Open/CreateXX: return $x\n">, + transfer Sys_Ret_OK ; bye with no errors +;Extended Open hooks check +OpenE2: ;AN000;;EO. + CMP AX,error_invalid_parameter ;AN000;;EO. IFS extended open ? + JNZ OpenE ;AN000;;EO. no. + JMP OpenCritLeave ;AN000;;EO. keep handle + +;Extended Open hooks check +; +; AL has error code. Stack has argument to dos_open/dos_create. +; +OpenClean: + fmt TypSysCall,LevLog,<"Return value from transpath $x\n">, + RestoreReg ; clean off stack +OpenE: + MOV [SI.SF_Ref_Count],0 ; release SFT + LDS SI,pJFN + MOV BYTE PTR [SI],0FFh ; free the SFN... + JMP SHORT OpenCritLeave + +OpenFail: + STI + RestoreReg ; Clean stack +OpenCritLeave: + MOV SFN,-1 ; remove mark. + fmt TypSysCall,LevLog,<"Open/CreateXX: error $x\n">, +;; File Tagging DOS 4.00 + CMP CS:[EXTERR],error_Code_Page_Mismatched ;AN000;;FT. code page mismatch + JNZ NORERR ;AN000;;FT. no + transfer From_GetSet ;AN000;;FT. yes +NORERR: ;AN000; + +;; File Tagging DOS 4.00 + transfer Sys_Ret_Err ; no free, return error + +EndProc $Open + +BREAK <$Creat - create a brand-new file> + +; +; $Creat - create the directory entry specified in DS:DX and give it the +; initial attributes contained in CX +; Inputs: DS:DX - ASCIZ path name +; CX - initial attributes +; Outputs: Carry set - AX has error code +; Carry reset - AX has handle +; Registers modified: all + +Procedure $Creat,NEAR + ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup + fmt TypSysCall,LevLog,<"Create\n"> + fmt TypSysCall,LevArgs,<" Att = $x file = '$S'\n">, +IF DBCS ;AN000; + MOV [Temp_Var],CX ;AN000;KK. set variable with attribute ;AN000; +ENDIF ;AN000; + SaveReg ; Save attributes on stack + MOV CX,OFFSET DOSGroup:DOS_Create; routine to call +AccessSet: + mov SAttrib,attr_hidden+attr_system + JMP AccessFile ; use good ol' open +EndProc $Creat + +BREAK <$CHMOD - change file attributes> +; +; Assembler usage: +; LDS DX, name +; MOV CX, attributes +; MOV AL,func (0=get, 1=set) +; INT 21h +; Error returns: +; AX = error_path_not_found +; AX = error_access_denied +; + + procedure $CHMOD,NEAR + ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup + MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer + SaveReg ; save function and attributes + MOV SI,DX ; get things in appropriate places + invoke TransPathSet ; get correct path + RestoreReg ; and get function and attrs back + JC ChModErr ; errors get mapped to path not found + Context DS ; set up for later possible calls + CMP cMeta,-1 + JNZ ChModErr + MOV [SAttrib],attr_hidden+attr_system+attr_directory + SUB AL,1 ; fast way to discriminate + JB ChModGet ; 0 -> go get value + JZ ChModSet ; 1 -> go set value + MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus + error error_invalid_function ; bad value +ChModGet: + invoke Get_File_Info ; suck out the ol' info + JC ChModE ; error codes are already set for ret + invoke Get_User_stack ; point to user saved vaiables + MOV [SI.User_CX],AX ; return the attributes + transfer Sys_Ret_OK ; say sayonara +ChModSet: + MOV AX,CX ; get attrs in position + invoke Set_File_Attribute ; go set + JC ChModE ; errors are set + transfer Sys_Ret_OK +ChModErr: + mov al,error_path_not_found +ChmodE: + Transfer SYS_RET_ERR +EndProc $ChMod + +BREAK <$UNLINK - delete a file entry> +; +; Assembler usage: +; LDS DX, name +; IF VIA SERVER DOS CALL +; MOV CX,SEARCH_ATTRIB +; MOV AH, Unlink +; INT 21h +; +; Error returns: +; AX = error_file_not_found +; = error_access_denied +; + + procedure $UNLINK,NEAR + ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup + SaveReg ; Save possible CX input parm + MOV SI,DX ; Point at input string + MOV DI,OFFSET DOSGroup:OpenBuf ; temp spot for path + invoke TransPathSet ; go get normalized path + RestoreReg + JC ChModErr ; badly formed path + CMP cMeta,-1 ; meta chars? + JNZ NotFound + Context DS + mov ch,attr_hidden+attr_system ; unlink appropriate files + call SetAttrib + invoke DOS_Delete ; remove that file + JC UnlinkE ; error is there + + + transfer Sys_Ret_OK ; okey doksy +NotFound: + MOV AL,error_path_not_found +UnlinkE: + transfer Sys_Ret_Err ; bye +EndProc $UnLink + +BREAK <$RENAME - move directory entries around> +; +; Assembler usage: +; LDS DX, source +; LES DI, dest +; IF VIA SERVER DOS CALL +; MOV CX,SEARCH_ATTRIB +; MOV AH, Rename +; INT 21h +; +; Error returns: +; AX = error_file_not_found +; = error_not_same_device +; = error_access_denied + + procedure $RENAME,NEAR + ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup + SaveReg ; save source and possible CX arg + PUSH ES + POP DS ; move dest to source + MOV SI,DI ; save for offsets + MOV DI,OFFSET DOSGroup:RenBuf + + MOV WORD PTR [NO_FILTER_DPATH],SI ;AN000;;IFS. save them for IFS + MOV WORD PTR [NO_FILTER_DPATH+2],DS ;AN000;;IFS. + + invoke TransPathSet ; munge the paths + PUSH WFP_Start ; get pointer + POP Ren_WFP ; stash it + RestoreReg ; get back source and possible CX arg +epjc2: JC ChModErr ; get old error + CMP cMeta,-1 + JNZ NotFound + SaveReg ; Save possible CX arg + MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer + invoke TransPathSet ; wham + RestoreReg + JC EPJC2 + Context DS + CMP cMeta,-1 + JB NotFound + + PUSH WORD PTR [THISCDS] ;AN000;;MS.save thiscds + PUSH WORD PTR [THISCDS+2] ;AN000;;MS. + MOV DI,OFFSET DOSGROUP:OpenBuf ;AN000;;MS. + PUSH SS ;AN000;;MS. + POP ES ;AN000;;MS.es:di-> source + XOR AL,AL ;AN000;;MS.scan all CDS +rnloop: ;AN000; + invoke GetCDSFromDrv ;AN000;;MS. + JC dorn ;AN000;;MS. end of CDS + invoke StrCmp ;AN000;;MS. current dir ? + JZ rnerr ;AN000;;MS. yes + INC AL ;AN000;;MS. next + JMP rnloop ;AN000;;MS. +rnerr: ;AN000; + ADD SP,4 ;AN000;;MS. pop thiscds + error error_current_directory ;AN000;;MS. +dorn: ;AN000; + POP WORD PTR SS:[THISCDS+2] ;AN000;;MS. + POP WORD PTR SS:[THISCDS] ;AN000;;MS. + Context DS + mov ch,attr_directory+attr_hidden+attr_system; rename appropriate files + call SetAttrib + invoke DOS_Rename ; do the deed + JC UnlinkE ; errors + + + transfer Sys_Ret_OK +EndProc $Rename + +Break <$CreateNewFile - Create a new directory entry> + +; +; CreateNew - Create a new directory entry. Return a file handle if there +; was no previous directory entry, and fail if a directory entry with +; the same name existed previously. +; +; Inputs: DS:DX point to an ASCIZ file name +; CX contains default file attributes +; Outputs: Carry Clear: +; AX has file handle opened for read/write +; Carry Set: +; AX has error code +; Registers modified: All + + Procedure $CreateNewFile,NEAR + ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup + fmt TypSysCall,LevLog,<"CreateNew\n"> + fmt TypSysCall,LevArgs,<" Att = $x file = '$S'\n">, +IF DBCS ;AN000; + MOV [Temp_Var],CX ;AN000;KK. set variable with attribute +ENDIF ;AN000; + SaveReg ; Save attributes on stack + MOV CX,OFFSET DOSGroup:DOS_Create_New ; routine to call + JMP AccessSet ; use good ol' open +EndProc $CreateNewFile + +Break + +; +; HexToAsciz - used to convert register into a hex number. +; +; Inputs: AX contains the number +; ES:DI point to destination +; Outputs: ES:DI updated +; Registers modified: DI,CX + +Procedure HexToAsciz,NEAR + mov cx,4 ; 4 digits in AX +GetDigit: + SaveReg ; preserve count + mov cl,4 + ROL AX,CL ; move leftmost nibble into rightmost + SaveReg ; preserve remainder of digits + AND AL,0Fh ; grab low nibble + ADD AL,'0' ; turn into digit + CMP AL,'9' ; bigger than 9 + JBE DoStore ; no, stash it + ADD AL,'A'-'0'-10 ; convert into uppercase letter +DoStore: + STOSB ; drop in the character + RestoreReg ; regain the number and count + loop GetDigit ; while there's more digits, go do 'em + return +EndProc HexToAsciz + +Break <$CreateTempFile - create a unique name> + +; +; $CreateTemp - given a directory, create a unique name in that directory. +; Method used is to get the current time, convert to a name and attempt +; a create new. Repeat until create new succeeds. +; +; Inputs: DS:DX point to a null terminated directory name. +; CX contains default attributes +; Outputs: Unique name is appended to DS:DX directory. +; AX has handle +; Registers modified: all + + Procedure $CreateTempFile,NEAR + ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup + fmt TypSysCall,LevLog,<"CreateTmp\n"> + fmt TypSysCall,LevArgs,<" Att = $x dir = '$S'\n">, +PUBLIC FILE001S,FILE001E +FILE001S: + LocalVar EndPtr,DWORD + LocalVar FilPtr,DWORD + LocalVar Attr,WORD +FILE001E: + Enter + TEST CX,NOT attr_changeable + JZ OKatts ; Ok if no non-changeable bits set +; +; We need this "hook" here to detect these cases (like user sets one both of +; vol_id and dir bits) because of the structure of the or $CreateNewFile loop +; below. The code loops on error_access_denied, but if one of the non +; changeable attributes is specified, the loop COULD be infinite or WILL be +; infinite because CreateNewFile will fail with access_denied always. Thus we +; need to detect these cases before getting to the loop. +; + MOV AX,error_access_denied + JMP SHORT SETTMPERR + +OKatts: + MOV attr,CX ; save attribute + MOV FilPtrL,DX ; pointer to file + MOV FilPtrH,DS + MOV EndPtrH,DS ; seg pointer to end of dir + PUSH DS + POP ES ; destination for nul search + MOV DI,DX + MOV CX,DI + NEG CX ; number of bytes remaining in segment + IF DBCS ;AN000; +Kloop: ;AN000;; 2/13/KK + MOV AL, BYTE PTR ES:[DI] ;AN000;; 2/13/KK + INC DI ;AN000;; 2/13/KK + OR AL,AL ;AN000;; 2/13/KK + JZ GOTEND ;AN000;; 2/13/KK + invoke testkanj ;AN000;; 2/13/KK + jz Kloop ;AN000;; 2/13/KK + inc di ;AN000;; Skip over second kanji byte 2/13/KK + CMP BYTE PTR ES:[DI],0 ;AN000;; 2/13/KK + JZ STOREPTH ;AN000; When char before NUL is sec Kanji byte + ;AN000; do not look for path char. 2/13/KK + jmp Kloop ;AN000; 2/13/KK +GOTEND: ;AN000; 2/13/KK + ELSE ;AN000; + OR CX,CX ;AN000;MS. cx=0 ? ds:dx on segment boundary + JNZ okok ;AN000;MS. no + MOV CX,-1 ;AN000;MS. +okok: ;AN000; + XOR AX,AX ;AN000; + REPNZ SCASB ;AN000; + ENDIF ;AN000; + DEC DI ; point back to the null + MOV AL,ES:[DI-1] ; Get char before the NUL + invoke PathChrCmp ; Is it a path separator? + JZ SETENDPTR ; Yes +STOREPTH: + MOV AL,'\' + STOSB ; Add a path separator (and INC DI) +SETENDPTR: + MOV EndPtrL,DI ; pointer to the tail +CreateLoop: + Context DS ; let ReadTime see variables + SaveReg + invoke ReadTime ; go get time + RestoreReg +; +; Time is in CX:DX. Go drop it into the string. +; + les di,EndPtr ; point to the string + mov ax,cx + call HexToAsciz ; store upper word + mov ax,dx + call HexToAsciz ; store lower word + xor al,al + STOSB ; nul terminate + LDS DX,FilPtr ; get name +ASSUME DS:NOTHING + MOV CX,Attr ; get attr + SaveReg + CALL $CreateNewFile ; try to create a new file + RestoreReg + JNC CreateDone ; failed, go try again +; +; The operation failed and the error has been mapped in AX. Grab the extended +; error and figure out what to do. +; + mov ax,ExtErr + cmp al,error_file_exists + jz CreateLoop ; file existed => try with new name + cmp al,error_access_denied + jz CreateLoop ; access denied (attr mismatch) + +; CMP AL,error_file_exists ; certain errors cause failure +; JZ CreateLoop +; CMP AL,error_access_denied +; JNZ SETTMPERR ; Error out +; CMP [EXTERR],error_cannot_make ; See if it's REALLY an att mismatch +; JNZ CreateLoop ; It was, try again +; MOV AL,error_cannot_make ; Return this "extended" error + +SETTMPERR: + STC +CreateDone: + Leave + JC CreateFail + transfer Sys_Ret_OK ; success! +CreateFail: + transfer Sys_Ret_Err +EndProc $CreateTempFile + +Break + +; +; SetAttrib will set the search attribute (SAttrib) either to the normal +; (CH) or to the value in CL if the current system call is through +; serverdoscall. +; +; Inputs: fSharing == FALSE => set sattrib to CH +; fSharing == TRUE => set sattrib to CL +; Outputs: none +; Registers changed: CX + +procedure SetAttrib,NEAR + assume ds:nothing,es:nothing + test fSharing,-1 + jnz Set + mov cl,ch +Set: + mov SAttrib,cl + return +EndProc SetAttrib + + +Break + +; Input: AL= 0 reserved AH=6CH +; BX= mode +; CL= create attribute CH=search attribute (from server) +; DX= flag +; DS:SI = file name +; ES:DI = parm list +; DD SET EA list (-1) null +; DW n parameters +; DB type (TTTTTTLL) +; DW IOMODE +; Function: Extended Open +; Output: carry clear +; AX= handle +; CX=1 file opened +; 2 file created/opened +; 3 file replaced/opened +; carry set: AX has error code +; + + +procedure $Extended_Open,NEAR ;AN000; + ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; + + MOV [XA_from],0 ;AN000;EO. init for set XA + MOV [EXTOPEN_FLAG],DX ;AN000;EO. save ext. open flag + MOV [EXTOPEN_IO_MODE],0 ;AN000;EO. initialize IO mode + TEST DX,reserved_bits_mask ;AN000;EO. reserved bits 0 ? + JNZ ext_inval2 ;AN000;EO. no + MOV AH,DL ;AN000;EO. make sure flag is right + CMP DL,0 ;AN000;EO. all fail ? + JZ ext_inval2 ;AN000;EO. yes, error + AND DL,exists_mask ;AN000;EO. get exists action byte + CMP DL,2 ;AN000;EO, > 02 + JA ext_inval2 ;AN000;EO. yes ,error + AND AH,not_exists_mask ;AN000;EO. get no exists action byte + CMP AH,10H ;AN000;EO. > 10 + JA ext_inval2 ;AN000;EO. yes error + +; CMP DI,-1 ;AN000;EO. null parm list +; JZ no_parm ;AN000;EO. yes +; ;AN000;EO +; PUSH CX ;AN000;EO. +; ;AN000;EO. +; MOV CX,ES:[DI.EXT_NUM_OF_PARM];AN000;EO. get number of parms +; OR CX,CX ;AN000;EO. 0 pamrs ? +; JZ parmend ;AN000;EO. yes +; PUSH SI ;AN000;EO. +; PUSH DS ;AN000;EO. +; MOV SI,DI ;AN000;EO. +; ADD SI,size EXT_OPEN_PARM ;AN000;EO. position to 1st parm +; PUSH ES ;AN000;EO. +; POP DS ;AN000;EO. ds:si -> parm list +; CALL GetIOParms ;AN000;EO. +; POP DS ;AN000;EO. +; POP SI ;AN000;EO. +;parmend: ;AN000;EO +; POP CX ;AN000;EO. restore CX +;no_parm: ;AN000;EO. + MOV [SAVE_ES],ES ;AN000;EO. save API parms + MOV [SAVE_DI],DI ;AN000;EO. + PUSH [EXTOPEN_FLAG] ;AN000;EO. + POP [SAVE_DX] ;AN000;EO. + MOV [SAVE_CX],CX ;AN000;EO. + MOV [SAVE_BX],BX ;AN000;EO. + MOV [SAVE_DS],DS ;AN000;EO. + MOV [SAVE_SI],SI ;AN000;EO. + MOV DX,SI ;AN000;EO. ds:dx points to file name + MOV AX,BX ;AN000;EO. ax= mode + +; TEST [EXTOPEN_FLAG],no_code_page_check ;AN000;EO. check no code page +; JNZ no_cdpg_chk ;AN000;;EO. no + JMP SHORT goopen2 ;AN000;;EO. do nromal +ext_inval2: ;AN000;;EO. + error error_Invalid_Function ;AN000;EO.. invalid function +ext_inval_parm: ;AN000;EO.. + POP CX ;AN000;EO.. pop up satck + POP SI ;AN000;EO.. + error error_Invalid_data ;AN000;EO.. invalid parms +error_return: ;AN000;EO. + ret ;AN000;EO.. return with error +;no_cdpg_chk: EO. +; MOV [CPSWFLAG],0 ;AN000;EO.. set CPSW flag off +goopen2: ;AN000; + TEST BX,int_24_error ;AN000;EO.. disable INT 24 error ? + JZ goopen ;AN000;EO.. no + OR [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;EO.. set bit to disable + +goopen: ;AN000; + OR [EXTOPEN_ON],EXT_OPEN_ON ;AN000;EO.. set Extended Open active + AND [EXTOPEN_FLAG],0FFH ;AN000;EO.create new ? + CMP [EXTOPEN_FLAG],ext_exists_fail + ext_nexists_create ;AN000;FT. + JNZ chknext ;AN000;;EO. no + invoke $CreateNewFile ;AN000;;EO. yes + JC error_return ;AN000;;EO. error + CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS does it + JZ ok_return2 ;AN000;;EO. yes + MOV [EXTOPEN_FLAG],action_created_opened ;AN000;EO. creted/opened + MOV [XA_from],By_Create ;AN000;;EO. for set xa + JMP setXAttr ;AN000;;EO. set XAs +ok_return2: + transfer SYS_RET_OK ;AN000;;EO. +chknext: + TEST [EXTOPEN_FLAG],ext_exists_open ;AN000;;EO. exists open + JNZ exist_open ;AN000;;EO. yes + invoke $Creat ;AN000;;EO. must be replace open + JC error_return ;AN000;;EO. return with error + CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS does it + JZ ok_return2 ;AN000;;EO. yes + MOV [EXTOPEN_FLAG],action_created_opened ;AN000;EO. prsume create/open + MOV [XA_from],By_Create ;AN000;EO. for set xa + TEST [EXTOPEN_ON],ext_file_not_exists ;AN000;;EO. file not exists ? + JNZ setXAttr ;AN000;;EO. no + MOV [EXTOPEN_FLAG],action_replaced_opened ;AN000;;EO. replaced/opened + MOV [XA_from],0 ;AN000;EO. for set xa + JMP SHORT setXAttr ;AN000;;EO. set XAs +error_return2: + ret ;AN000;;EO. return with error + ;AN000; +exist_open: ;AN000; + test fSharing,-1 ;AN000;;EO. server doscall? + jz noserver ;AN000;;EO. no + MOV CL,CH ;AN000;;EO. cl=search attribute + +noserver: + invoke $Open2 ;AN000;;EO. do open + JNC ext_ok ;AN000;;EO. + CMP [EXTOPEN_ON],0 ;AN000;;EO. error and IFS call + JZ error_return2 ;AN000;;EO. return with error +local_extopen: + + CMP AX,error_file_not_found ;AN000;;EO. file not found error + JNZ error_return2 ;AN000;;EO. no, + TEST [EXTOPEN_FLAG],ext_nexists_create;AN000;;EO. want to fail + JNZ do_creat ;AN000;;EO. yes + JMP extexit ;AN000;;EO. yes +do_creat: + MOV [XA_from],By_Create ;AN000;;EO. for set xa + MOV CX,[SAVE_CX] ;AN000;;EO. get ds:dx for file name + LDS SI,DWORD PTR [SAVE_SI] ;AN000;;EO. cx = attribute + MOV DX,SI ;AN000;;EO. + invoke $Creat ;AN000;;EO. do create + JC extexit ;AN000;;EO. error + MOV [EXTOPEN_FLAG],action_created_opened ;AN000;;EO. is created/opened + JMP SHORT setXAttr ;AN000;;EO. set XAs + +ext_ok: + CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS call ? + JZ ok_return ;AN000;;EO. yes + MOV [EXTOPEN_FLAG],action_opened ;AN000;;EO. opened +setXAttr: +; LES DI,DWORD PTR [SAVE_DI] ;AN000;EO. + PUSH AX ;AN000;;EO. save handle for final +; MOV BX,AX ;AN000;;EO. bx= handle +; MOV AX,04H ;AN000;;EO. set extended attr by handle +; PUSH DS ;AN000;;EO. save file name addr +; PUSH DX ;AN000;;EO. +; CMP DI,-1 ;AN000;;EO. null parm list +; JZ nosetea ;AN000;;EO. yes +; CMP WORD PTR ES:[DI],-1 ;AN000;;EO. null set list +; JZ nosetea ;AN000;;EO. yes +; LES DI,DWORD PTR ES:[DI] ;AN000;;EO. es:di -> set list +; invoke $File_times ;AN000;;EO. +;nosetea: ;AN000; EO +; POP DX ;AN000;;EO. restore file name addr +; POP DS ;AN000;;EO. +; JC extexit2 ;AN000;;EO. + invoke get_user_stack ;AN000;;EO. + MOV AX,[EXTOPEN_FLAG] ;AN000;;EO. + MOV [SI.USER_CX],AX ;AN000;;EO. set action code for cx + POP AX ;AN000;;EO. + MOV [SI.USER_AX],AX ;AN000;;EO. set handle for ax + +ok_return: ;AN000; + transfer SYS_RET_OK ;AN000;;EO. + +extexit2: ;AN000; ERROR RECOVERY + + POP BX ;AN000;EO. close the handle + PUSH AX ;AN000;EO. save error code from set XA + CMP [EXTOPEN_FLAG],action_created_opened ;AN000;EO. from create + JNZ justopen ;AN000;EO. + LDS SI,DWORD PTR [SAVE_SI] ;AN000;EO. cx = attribute + LDS DX,DWORD PTR [SI] ;AN000;EO. + invoke $UNLINK ;AN000;EO. delete the file + JMP SHORT reserror ;AN000;EO. + +justopen: ;AN000; + invoke $close ;AN000;EO. pretend never happend +reserror: ;AN000; + POP AX ;AN000;EO. retore error code from set XA + JMP SHORT extexit ;AN000;EO. + + +ext_file_unfound: ;AN000; + MOV AX,error_file_not_found ;AN000;EO. + JMP SHORT extexit ;AN000;EO. +ext_inval: ;AN000; + MOV AX,error_invalid_function;AN000;EO. +extexit: + transfer SYS_RET_ERR ;AN000;EO. + +EndProc $Extended_Open ;AN000; + + +Break + +; +; +; Inputs: DS:SI -> IO parm list +; CX= number of parms +; Function: get IO parms from parm list +; Outputs: [EXT_IOMODE]= IO mode parm + +;procedure GetIOParms,NEAR +; assume ds:nothing,es:nothing +; +; LODSB ; get parm type ;AN000; +; CMP AL,0*100B+10B ; have IOMODE ;AN000; +; JE SET_IOMODE ;AN000; +; AND AL,00000011B ; decode it ;AN000; +; JZ SKIP_ASCIIZ ;AN000; +; DEC AL ;AN000; +; JZ SKIP_LEN ;AN000; +;; DEC AL ;AN000; +; JZ SKIP_WORD ;AN000; +;SKIP_DWORD: ; copy DWORD parm ;AN000; +; LODSW ;AN000; +;SKIP_WORD: ; copy WORD parm ;AN000; +; LODSW ;AN000; +; JMP SHORT NEXT_PARM ;AN000; +;SET_IOMODE: ; copy IOMODE ;AN000; +; LODSW ;AN000; +; MOV [EXTOPEN_IO_MODE],AX ;AN000; +; JMP SHORT NEXT_PARM ;AN000; +;SKIP_LEN: ; copy LENGTH parm ;AN000; +; LODSW ;AN000; +; ADD SI,AX ;AN000; +; JMP SHORT NEXT_PARM ;AN000; +;SKIP_ASCIIZ: ; copy ASCIIZ parm ;AN000; +; LODSB ;AN000; +; OR AL,AL ;AN000; +; JNE SKIP_ASCIIZ ;AN000; +;NEXT_PARM: ;AN000; +; LOOP GetIOParms ;AN000; +; return ;AN000; +;EndProc GetIOParms ;AN000; + + +CODE ENDS +END + \ No newline at end of file -- cgit v1.2.3