From 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Fri, 12 Aug 1983 17:53:34 -0700 Subject: MS-DOS v2.0 Release --- v2.0/source/DIRCALL.ASM | 507 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 507 insertions(+) create mode 100644 v2.0/source/DIRCALL.ASM (limited to 'v2.0/source/DIRCALL.ASM') diff --git a/v2.0/source/DIRCALL.ASM b/v2.0/source/DIRCALL.ASM new file mode 100644 index 0000000..db55ab8 --- /dev/null +++ b/v2.0/source/DIRCALL.ASM @@ -0,0 +1,507 @@ +TITLE DIRCALL - Directory manipulation internal calls +NAME DIRCALL + +; $MKDIR +; $CHDIR +; $RMDIR + +.xlist +INCLUDE DOSSEG.ASM + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME SS:DOSGROUP,CS:DOSGROUP + +.xcref +INCLUDE DOSSYM.ASM +INCLUDE DEVSYM.ASM +.cref +.list + +ifndef Kanji +Kanji equ 0 +endif + + i_need AUXSTACK,BYTE + i_need NoSetDir,BYTE + i_need CURBUF, DWORD + i_need DIRSTART,WORD + i_need THISDPB,DWORD + i_need NAME1,BYTE + i_need LASTENT,WORD + i_need ATTRIB,BYTE + i_need THISFCB,DWORD + i_need AUXSTACK,BYTE + i_need CREATING,BYTE + i_need DRIVESPEC,BYTE + i_need ROOTSTART,BYTE + i_need SWITCH_CHARACTER,BYTE + + extrn sys_ret_ok:near,sys_ret_err:near + + +; XENIX CALLS +BREAK <$MkDir - Make a directory entry> +MKNERRJ: JMP MKNERR +NODEEXISTSJ: JMP NODEEXISTS + procedure $MKDIR,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; DS:DX Points to asciz name +; Function: +; Make a new directory +; Returns: +; STD XENIX Return +; AX = mkdir_path_not_found if path bad +; AX = mkdir_access_denied If +; Directory cannot be created +; Node already exists +; Device name given +; Disk or directory(root) full + invoke validate_path + JC MKNERRJ + MOV SI,DX + MOV WORD PTR [THISFCB+2],SS + MOV WORD PTR [THISFCB],OFFSET DOSGROUP:AUXSTACK-40 ; Scratch space + MOV AL,attr_directory + MOV WORD PTR [CREATING],0E500h + invoke MAKENODE +ASSUME DS:DOSGROUP + MOV AL,mkdir_path_not_found + JC MKNERRJ + JNZ NODEEXISTSJ + LDS DI,[CURBUF] +ASSUME DS:NOTHING + SUB SI,DI + PUSH SI ; Pointer to fcb_FIRCLUS + PUSH [DI.BUFSECNO] ; Sector of new node + PUSH SS + POP DS +ASSUME DS:DOSGROUP + PUSH [DIRSTART] ; Parent for .. entry + XOR AX,AX + MOV [DIRSTART],AX ; Null directory + invoke NEWDIR + JC NODEEXISTSPOPDEL ; No room + invoke GETENT ; First entry + LES DI,[CURBUF] + MOV ES:[DI.BUFDIRTY],1 + ADD DI,BUFINSIZ ; Point at buffer + MOV AX,202EH ; ". " + STOSW + MOV DX,[DIRSTART] ; Point at itself + invoke SETDOTENT + MOV AX,2E2EH ; ".." + STOSW + POP DX ; Parent + invoke SETDOTENT + LES BP,[THISDPB] + POP DX ; Entry sector + XOR AL,AL ; Pre read + invoke GETBUFFR + MOV DX,[DIRSTART] + LDS DI,[CURBUF] +ASSUME DS:NOTHING +ZAPENT: + POP SI ; fcb_Firclus pointer + ADD SI,DI + MOV [SI],DX + XOR DX,DX + MOV [SI+2],DX + MOV [SI+4],DX +DIRUP: + MOV [DI.BUFDIRTY],1 + PUSH SS + POP DS +ASSUME DS:DOSGROUP + MOV AL,ES:[BP.dpb_drive] + invoke FLUSHBUF +SYS_RET_OKJ: + JMP SYS_RET_OK + +NODEEXISTSPOPDEL: + POP DX ; Parent + POP DX ; Entry sector + LES BP,[THISDPB] + XOR AL,AL ; Pre read + invoke GETBUFFR + LDS DI,[CURBUF] +ASSUME DS:NOTHING + POP SI ; dir_first pointer + ADD SI,DI + SUB SI,dir_first ; Point back to start of dir entry + MOV BYTE PTR [SI],0E5H ; Free the entry + CALL DIRUP +NODEEXISTS: + MOV AL,mkdir_access_denied +MKNERR: + JMP SYS_RET_ERR +$MKDIR ENDP + +BREAK <$ChDir -- Change current directory on a drive> + procedure $CHDIR,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; DS:DX Points to asciz name +; Function: +; Change current directory +; Returns: +; STD XENIX Return +; AX = chdir_path_not_found if error + + invoke validate_path + JC PathTooLong + + PUSH DS + PUSH DX + MOV SI,DX + invoke GETPATH + JC PATHNOGOOD + JNZ PATHNOGOOD +ASSUME DS:DOSGROUP + MOV AX,[DIRSTART] + MOV BX,AX + XCHG BX,ES:[BP.dpb_current_dir] + OR AX,AX + POP SI + POP DS +ASSUME DS:NOTHING + JZ SYS_RET_OKJ + MOV DI,BP + ADD DI,dpb_dir_text + MOV DX,DI + CMP [DRIVESPEC],0 + JZ NODRIVESPEC + INC SI + INC SI +NODRIVESPEC: + MOV CX,SI + CMP [ROOTSTART],0 + JZ NOTROOTPATH + INC SI + INC CX + JMP SHORT COPYTHESTRINGBXZ +NOTROOTPATH: + OR BX,BX ; Previous path root? + JZ COPYTHESTRING ; Yes + XOR BX,BX +ENDLOOP: + CMP BYTE PTR ES:[DI],0 + JZ PATHEND + INC DI + INC BX + JMP SHORT ENDLOOP +PATHEND: + MOV AL,'/' + CMP AL,[switch_character] + JNZ SLASHOK + MOV AL,'\' ; Use the alternate character +SLASHOK: + STOSB + INC BX + JMP SHORT CHECK_LEN + +PATHNOGOOD: + POP AX + POP AX +PATHTOOLONG: + error error_path_not_found + +ASSUME DS:NOTHING + +INCBXCHK: + INC BX +BXCHK: + CMP BX,DIRSTRLEN + return + +COPYTHESTRINGBXZ: + XOR BX,BX +COPYTHESTRING: + LODSB + OR AL,AL + + JNZ FOOB + JMP CPSTDONE +FOOB: + CMP AL,'.' + JZ SEEDOT + CALL COPYELEM +CHECK_LEN: + CMP BX,DIRSTRLEN + JB COPYTHESTRING + MOV AL,ES:[DI-1] + invoke PATHCHRCMP + JNZ OK_DI + DEC DI +OK_DI: + XOR AL,AL + STOSB ; Correctly terminate the path + MOV ES:[BP.dpb_current_dir],-1 ; Force re-validation + JMP SHORT PATHTOOLONG + +SEEDOT: + LODSB + OR AL,AL ; Check for null + JZ CPSTDONEDEC + CMP AL,'.' + JNZ COPYTHESTRING ; eat ./ + CALL DELELMES ; have .. + LODSB ; eat the / + OR AL,AL ; Check for null + JZ CPSTDONEDEC + JMP SHORT COPYTHESTRING + +; Copy one element from DS:SI to ES:DI include trailing / not trailing null +; LODSB has already been done +COPYELEM: + PUSH DI ; Save in case too long + PUSH CX + MOV CX,800h ; length of filename + MOV AH,'.' ; char to stop on + CALL CopyPiece ; go for it! + CALL BXCHK ; did we go over? + JAE POPCXDI ; yep, go home + CMP AH,AL ; did we stop on .? + JZ CopyExt ; yes, go copy ext + OR AL,AL ; did we end on nul? + JZ DECSIRet ; yes, bye +CopyPathEnd: + STOSB ; save the path char + CALL INCBXCHK ; was there room for it? + JAE POPCXDI ; Nope + INC SI ; guard against following dec +DECSIRET: + DEC SI ; point back at null + POP CX + POP AX ; toss away saved DI + return +POPCXDI: + POP CX ; restore + POP DI ; point back... + return +CopyExt: + STOSB ; save the dot + CALL INCBXCHK ; room? + JAE POPCXDI ; nope. + LODSB ; get next char + XOR AH,AH ; NUL here + MOV CX,300h ; at most 3 chars + CALL CopyPiece ; go copy it + CALL BXCHK ; did we go over + JAE POPCXDI ; yep + OR AL,AL ; sucessful end? + JZ DECSIRET ; yes + JMP CopyPathEnd ; go stash path char + +DELELMES: +; Delete one path element from ES:DI + DEC DI ; the '/' + DEC BX + + IF KANJI + PUSH AX + PUSH CX + PUSH DI + PUSH DX + MOV CX,DI + MOV DI,DX +DELLOOP: + CMP DI,CX + JZ GOTDELE + MOV AL,ES:[DI] + INC DI + invoke TESTKANJ + JZ NOTKANJ11 + INC DI + JMP DELLOOP + +NOTKANJ11: + invoke PATHCHRCMP + JNZ DELLOOP + MOV DX,DI ; Point to char after '/' + JMP DELLOOP + +GOTDELE: + MOV DI,DX + POP DX + POP AX ; Initial DI + SUB AX,DI ; Distance moved + SUB BX,AX ; Set correct BX + POP CX + POP AX + return + ELSE +DELLOOP: + CMP DI,DX + retz + PUSH AX + MOV AL,ES:[DI-1] + invoke PATHCHRCMP + POP AX + retz + DEC DI + DEC BX + JMP SHORT DELLOOP + ENDIF + +CPSTDONEDEC: + DEC DI ; Back up over trailing / +CPSTDONE: + STOSB ; The NUL + JMP SYS_RET_OK + +; copy a piece CH chars max until the char in AH (or path or NUL) +CopyPiece: + STOSB ; store the character + INC CL ; moved a byte + CALL INCBXCHK ; room enough? + JAE CopyPieceRet ; no, pop CX and DI + OR AL,AL ; end of string? + JZ CopyPieceRet ; yes, dec si and return + + IF KANJI + CALL TestKanj ; was it kanji? + JZ NotKanj ; nope + MOVSB ; move the next byte + CALL INCBXCHK ; room for it? + JAE CopyPieceRet ; nope + INC CL ; moved a byte +NotKanj: + ENDIF + + CMP CL,CH ; move too many? + JBE CopyPieceNext ; nope + + IF KANJI + CALL TestKanj ; was the last byte kanji + JZ NotKanj2 ; no only single byte backup + DEC DI ; back up a char + DEC BX +NotKanj2: + ENDIF + + DEC DI ; back up a char + DEC BX +CopyPieceNext: + LODSB ; get next character + invoke PathChrCmp ; end of road? + JZ CopyPieceRet ; yep, return and don't dec SI + CMP AL,AH ; end of filename? + JNZ CopyPiece ; go do name +CopyPieceRet: + return ; bye! + +$CHDIR ENDP + +BREAK <$RmDir -- Remove a directory> +NOPATHJ: JMP NOPATH + + procedure $RMDIR,NEAR ; System call 47 +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; DS:DX Points to asciz name +; Function: +; Delete directory if empty +; Returns: +; STD XENIX Return +; AX = rmdir_path_not_found If path bad +; AX = rmdir_access_denied If +; Directory not empty +; Path not directory +; Root directory specified +; Directory malformed (. and .. not first two entries) +; AX = rmdir_current_directory + + invoke Validate_path + JC NoPathJ + MOV SI,DX + invoke GETPATH + JC NOPATHJ +ASSUME DS:DOSGROUP + JNZ NOTDIRPATH + MOV DI,[DIRSTART] + OR DI,DI + JZ NOTDIRPATH + MOV CX,ES:[BP.dpb_current_dir] + CMP CX,-1 + JNZ rmdir_current_dir_check + invoke GetCurrDir + invoke Get_user_stack + MOV DX,[SI.user_DX] + MOV DS,[SI.user_DS] + JMP $RMDIR + +NOTDIRPATHPOP: + POP AX + POP AX +NOTDIRPATH: + error error_access_denied + +rmdir_current_dir_check: + CMP DI,CX + JNZ rmdir_get_buf + error error_current_directory + +rmdir_get_buf: + LDS DI,[CURBUF] +ASSUME DS:NOTHING + SUB BX,DI + PUSH BX ; Save entry pointer + PUSH [DI.BUFSECNO] ; Save sector number + PUSH SS + POP DS +ASSUME DS:DOSGROUP + PUSH SS + POP ES + MOV DI,OFFSET DOSGROUP:NAME1 + MOV AL,'?' + MOV CX,11 + REP STOSB + XOR AL,AL + STOSB + invoke STARTSRCH + invoke GETENTRY + MOV DS,WORD PTR [CURBUF+2] +ASSUME DS:NOTHING + MOV SI,BX + LODSW + CMP AX,(' ' SHL 8) OR '.' + JNZ NOTDIRPATHPOP + ADD SI,32-2 + LODSW + CMP AX,('.' SHL 8) OR '.' + JNZ NOTDIRPATHPOP + PUSH SS + POP DS +ASSUME DS:DOSGROUP + MOV [LASTENT],2 ; Skip . and .. + invoke GETENTRY + MOV [ATTRIB],attr_directory+attr_hidden+attr_system + invoke SRCH + JNC NOTDIRPATHPOP + LES BP,[THISDPB] + MOV BX,[DIRSTART] + invoke RELEASE + POP DX + XOR AL,AL + invoke GETBUFFR + LDS DI,[CURBUF] +ASSUME DS:NOTHING + POP BX + ADD BX,DI + MOV BYTE PTR [BX],0E5H ; Free the entry + JMP DIRUP + +NOPATH: + error error_path_not_found + +$RMDIR ENDP + + do_ext + +CODE ENDS + END + \ No newline at end of file -- cgit v1.2.3