711 lines
18 KiB
NASM
711 lines
18 KiB
NASM
page ,132
|
||
; SCCSID = @(#)tenv2.asm 1.1 85/05/14
|
||
; SCCSID = @(#)tenv2.asm 1.1 85/05/14
|
||
TITLE Part6 COMMAND Transient routines.
|
||
;/*
|
||
; * Microsoft Confidential
|
||
; * Copyright (C) Microsoft Corporation 1991
|
||
; * All Rights Reserved.
|
||
; */
|
||
|
||
; Environment utilities and misc. routines
|
||
|
||
.xlist
|
||
.xcref
|
||
include comsw.asm
|
||
include dossym.inc
|
||
include syscall.inc
|
||
include find.inc
|
||
include comseg.asm
|
||
include comequ.asm
|
||
.list
|
||
.cref
|
||
|
||
|
||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||
EXTRN pipeflag:byte
|
||
DATARES ENDS
|
||
|
||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||
EXTRN ACRLF_PTR:WORD
|
||
EXTRN BadCD_Ptr:WORD
|
||
EXTRN Badmkd_ptr:word
|
||
EXTRN BADRMD_PTR:WORD
|
||
EXTRN Extend_buf_ptr:word ;AN000;
|
||
EXTRN Extend_buf_sub:byte ;AN022;
|
||
EXTRN MD_exists_ptr:word ;AN006;
|
||
EXTRN msg_disp_class:byte ;AC000;
|
||
EXTRN NOSPACE_PTR:WORD
|
||
EXTRN parse_chdir:byte ;AC000;
|
||
EXTRN parse_mrdir:byte ;AC000;
|
||
EXTRN PIPEEMES_PTR:WORD
|
||
EXTRN string_buf_ptr:word
|
||
TRANDATA ENDS
|
||
|
||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||
EXTRN CURDRV:BYTE
|
||
EXTRN DESTINFO:BYTE
|
||
EXTRN DESTTAIL:WORD
|
||
EXTRN DIRCHAR:BYTE
|
||
EXTRN dirflag:byte ;AN015;
|
||
EXTRN KPARSE:BYTE ;AC000; 3/3/KK
|
||
EXTRN msg_numb:word ;AN022;
|
||
EXTRN parse1_addr:dword ;AC000;
|
||
EXTRN parse1_type:byte ;AC000;
|
||
EXTRN PATHPOS:WORD
|
||
EXTRN RESSEG:WORD
|
||
EXTRN srcxname:byte ;AC000;
|
||
EXTRN string_ptr_2:word
|
||
EXTRN SWITCHAR:BYTE
|
||
EXTRN USERDIR1:BYTE
|
||
TRANSPACE ENDS
|
||
|
||
TRANCODE SEGMENT PUBLIC byte
|
||
|
||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||
|
||
EXTRN cerror:near
|
||
|
||
PUBLIC $chdir
|
||
PUBLIC $mkdir
|
||
PUBLIC $rmdir
|
||
PUBLIC crlf2
|
||
PUBLIC crprint
|
||
PUBLIC delim
|
||
PUBLIC error_output
|
||
PUBLIC fcb_to_ascz
|
||
PUBLIC pathchrcmp
|
||
PUBLIC pathcrunch
|
||
PUBLIC savudir
|
||
PUBLIC savudir1
|
||
PUBLIC scanoff
|
||
PUBLIC strcomp
|
||
|
||
break $Chdir
|
||
|
||
; ****************************************************************
|
||
; *
|
||
; * ROUTINE: $CHDIR
|
||
; *
|
||
; * FUNCTION: Entry point for CHDIR command. Parse the command
|
||
; * line. If path is found, CHDIR to path. If a drive
|
||
; * letter is found, get and display the current dir
|
||
; * of the specified drive. If nothing is found, get
|
||
; * and display the current dir of the default drive.
|
||
; *
|
||
; * INPUT: command line at offset 81H
|
||
; *
|
||
; * OUTPUT: none
|
||
; *
|
||
; ****************************************************************
|
||
|
||
assume ds:trangroup,es:trangroup
|
||
|
||
$CHDIR:
|
||
|
||
mov si,81H
|
||
mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR
|
||
xor cx,cx ;AN000; clear cx,dx
|
||
xor dx,dx ;AN000;
|
||
invoke parse_with_msg ;AC018; call parser
|
||
|
||
cmp ax,end_of_line ;AC000; are we at end of line?
|
||
jz bwdJ ; No args
|
||
cmp ax,result_no_error ;AC000; did we have an error?
|
||
jnz ChDirErr ;AC018; yes - exit
|
||
|
||
cmp parse1_type,result_drive ;AC000; was a drive entered?
|
||
jnz REALCD ; no
|
||
;
|
||
; D: was found. See if there is anything more.
|
||
;
|
||
mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir
|
||
xor dx,dx ;AC000;
|
||
invoke parse_check_eol ;AC000; call parser
|
||
jnz ChDirErr ;AC000;
|
||
|
||
bwdJ:
|
||
invoke build_dir_for_chdir ; Drive only specified
|
||
call crlf2
|
||
return
|
||
|
||
REALCD:
|
||
|
||
push si ;AN000; save position in line
|
||
lds si,parse1_addr ;AN000; get address of filespec
|
||
invoke move_to_srcbuf ;AN000; move to srcbuf
|
||
pop si ;AN000; restore position in line
|
||
mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir
|
||
xor dx,dx ;AC000;
|
||
invoke parse_check_eol ;AC000; call parser
|
||
jnz ChDirErr ;AC000;
|
||
|
||
invoke SETPATH
|
||
TEST [DESTINFO],2
|
||
JNZ BadChdir
|
||
MOV AH,CHDIR
|
||
INT 21h
|
||
retnc
|
||
|
||
invoke get_ext_error_number ;AN022; get the extended error
|
||
cmp ax,error_path_not_found ;AN022; see if path not found
|
||
jz BadChDir ;AN022; yes - issue old message
|
||
;SR;
|
||
; We want to issue "Invalid Directory" message even if the path is valid
|
||
;but is not a directory. The extended error returns "Access denied" which
|
||
;is kind of confusing. Issue the old message if access denied error is
|
||
;returned
|
||
;
|
||
cmp ax,error_access_denied
|
||
jz BadChDir
|
||
|
||
call Set_Ext_Error_Subst ;AN022;
|
||
jmp short chdirerr ;AN022;
|
||
|
||
BadChDir:
|
||
MOV DX,OFFSET TRANGROUP:BADCD_ptr
|
||
|
||
ChDirErr:
|
||
invoke Std_Eprintf
|
||
return
|
||
|
||
break $Mkdir
|
||
|
||
assume ds:trangroup,es:trangroup
|
||
|
||
$MKDIR:
|
||
CALL SETRMMK
|
||
JC MkDirErr
|
||
MOV AH,MKDIR
|
||
INT 21h
|
||
retnc
|
||
|
||
invoke get_ext_error_number ;AN022; get the extended error
|
||
cmp ax,error_path_not_found ;AN022; see if path not found
|
||
jz MD_other_err ;AN022; yes - issue old message
|
||
cmp ax,error_access_denied ;AN022; access denied?
|
||
jz badmderr ;AN022; yes - see if file exists
|
||
|
||
call Set_Ext_Error_Subst ;AN022;
|
||
jmp short MkDirerr ;AC022; yes - go print it
|
||
|
||
BADMDERR:
|
||
mov dx,offset trangroup:srcxname ;AN006; Set Disk transfer address
|
||
mov ah,Set_DMA ;AN006;
|
||
int 21h ;AN006;
|
||
MOV AH,Find_First ;AN006; see if file/dir exists
|
||
mov cx,attr_directory ;AN006; search for directory
|
||
INT 21h ;AN006;
|
||
jc MD_other_err ;AN006; doesn't exist - must be something else
|
||
mov dl,srcxname.find_buf_attr ;AN006; we found a file/dir
|
||
test dl,attr_directory ;AN006; was it a directory?
|
||
jz MD_other_err ;AN006; no - must have been a file
|
||
mov dx,offset trangroup:MD_exists_ptr ;AN006; set up already exists error
|
||
jmp short MkDirErr ;AN006; make sure we didn't have network error
|
||
MD_other_err: ;AN006;
|
||
MOV DX,OFFSET TRANGROUP:BADMKD_ptr
|
||
MkDirErr:
|
||
invoke Std_Eprintf
|
||
return
|
||
|
||
Break <Common MkDir/RmDir set up code>
|
||
|
||
;****************************************************************
|
||
;*
|
||
;* ROUTINE: SETRMMK
|
||
;*
|
||
;* FUNCTION: Parse routine for the internal MKDIR and RMDIR
|
||
;* commands. Parses the command line for a required
|
||
;* filespec.
|
||
;*
|
||
;* INPUT: command line at offset 81H
|
||
;*
|
||
;* OUTPUT: carry clear
|
||
;* DS:DX points to ASCIIZ argument
|
||
;* carry set
|
||
;* DS:DX has error message pointer
|
||
;*
|
||
;****************************************************************
|
||
|
||
SETRMMK:
|
||
mov si,81H
|
||
mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR
|
||
xor cx,cx ;AN000; clear cx,dx
|
||
xor dx,dx ;AN000;
|
||
invoke parse_with_msg ;AC000; call parser
|
||
cmp ax,result_no_error ;AC000; did we have an error?
|
||
jnz NOARGERR ;AC000; yes - exit
|
||
|
||
mov di,offset trangroup:srcxname ;AN000; get address of srcxname
|
||
push di ;AN000; save address
|
||
push si ;AN000; save position in line
|
||
lds si,parse1_addr ;AN000; get address of path
|
||
|
||
mrdir_move_filename: ;AN000; put filespec in srcxname
|
||
lodsb ;get a char from buffer
|
||
stosb ;AN000; store in srcxname
|
||
cmp al,end_of_line_out ;AC000; it char a terminator?
|
||
jnz mrdir_move_filename ;AC000; no - keep moving
|
||
pop si ;AN000; get line position back
|
||
|
||
;
|
||
; we have scanned an argument. See if any args beyond.
|
||
;
|
||
|
||
mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir
|
||
invoke parse_check_eol ;AC000; are we at end of line?
|
||
pop dx ;AC000; get address of SRCXNAME
|
||
retz ;yes - return no error
|
||
NOARGERR:
|
||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||
XOR AX,AX
|
||
STC
|
||
return
|
||
|
||
break $Rmdir
|
||
|
||
assume ds:trangroup,es:trangroup
|
||
|
||
$RMDIR:
|
||
CALL SETRMMK
|
||
JC RmDirErr
|
||
JNZ BADRDERR
|
||
MOV AH,RMDIR
|
||
INT 21h
|
||
retnc
|
||
|
||
invoke get_ext_error_number ;AN022; get the extended error
|
||
cmp ax,error_path_not_found ;AN022; see if path not found
|
||
jz badrderr ;AN022; yes - issue old message
|
||
cmp ax,error_access_denied ;AN022; access denied?
|
||
jz badrderr ;AN022; yes - issue old message
|
||
|
||
call Set_Ext_Error_Subst ;AN022;
|
||
jmp short RmDirerr ;AC022; yes - go print it
|
||
|
||
BADRDERR:
|
||
MOV DX,OFFSET TRANGROUP:BADRMD_ptr
|
||
|
||
RmDirErr:
|
||
invoke STD_Eprintf
|
||
return
|
||
|
||
;****************************************************************
|
||
;*
|
||
;* ROUTINE: Set_ext_error_subst
|
||
;*
|
||
;* FUNCTION: Sets up substitution for extended error
|
||
;*
|
||
;* INPUT: AX - extended error number
|
||
;* DX - offset of string
|
||
;*
|
||
;* OUTPUT: Extend_Buf_Ptr set up for STD_EPRINTF
|
||
;*
|
||
;****************************************************************
|
||
|
||
Set_ext_error_subst proc near ;AN022;
|
||
|
||
mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class
|
||
mov string_ptr_2,dx ;AN022; get address of failed string
|
||
mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block
|
||
mov dx,offset TranGroup:Extend_Buf_ptr ;AN022; get extended message pointer
|
||
mov Extend_Buf_ptr,ax ;AN022; get message number in control block
|
||
|
||
ret ;AN022; return
|
||
|
||
Set_ext_error_subst endp ;AN022;
|
||
|
||
|
||
|
||
|
||
|
||
Break <SavUDir - preserve the users current directory on a particular drive>
|
||
|
||
;
|
||
; SavUDir - move the user's current directory on a drive into UserDir1
|
||
; SavUDir1 - move the user's current directory on a drive into a specified
|
||
; buffer
|
||
;
|
||
; Inputs: DL has 1-based drive number
|
||
; ES:DI has destination buffer (SavUDir1 only)
|
||
; Outputs: Carry Clear
|
||
; DS = TranGroup
|
||
; Carry Set
|
||
; AX has error code
|
||
; Registers Modified: AX, SI
|
||
;
|
||
|
||
SAVUDIR:
|
||
MOV DI,OFFSET TRANGROUP:USERDIR1
|
||
|
||
SAVUDIR1:
|
||
MOV AL,DL
|
||
ADD AL,'@'
|
||
CMP AL,'@'
|
||
JNZ GOTUDRV
|
||
ADD AL,[CURDRV]
|
||
INC AL ; A = 1
|
||
|
||
GOTUDRV:
|
||
STOSB
|
||
MOV AH,[DIRCHAR]
|
||
MOV AL,':'
|
||
STOSW
|
||
PUSH ES
|
||
POP DS
|
||
ASSUME DS:NOTHING
|
||
|
||
MOV SI,DI
|
||
MOV AH,CURRENT_DIR ; Get the Directory Text
|
||
INT 21h
|
||
retc
|
||
PUSH CS
|
||
POP DS
|
||
ASSUME DS:TRANGROUP
|
||
|
||
return
|
||
|
||
|
||
CRLF2:
|
||
PUSH DX
|
||
MOV DX,OFFSET TRANGROUP:ACRLF_ptr
|
||
|
||
PR:
|
||
PUSH DS
|
||
PUSH CS
|
||
POP DS
|
||
invoke std_printf
|
||
POP DS
|
||
POP DX
|
||
|
||
return
|
||
|
||
;
|
||
; These routines (SCANOFF, DELIM) are called in batch processing when DS
|
||
; may NOT be TRANGROUP
|
||
;
|
||
ASSUME DS:NOTHING,ES:NOTHING
|
||
|
||
SCANOFF:
|
||
LODSB
|
||
CALL DELIM
|
||
JZ SCANOFF
|
||
DEC SI ; Point to first non-delimiter
|
||
return
|
||
|
||
;
|
||
; Input: AL is character to classify
|
||
; Output: Z set if delimiter
|
||
; NZ set otherwise
|
||
; Registers modified: none
|
||
;
|
||
|
||
DELIM:
|
||
CMP AL,' '
|
||
retz
|
||
CMP AL,'='
|
||
retz
|
||
CMP AL,','
|
||
retz
|
||
CMP AL,';'
|
||
retz
|
||
CMP AL,9 ; Check for TAB character
|
||
retz
|
||
CMP AL,0ah ; Check for line feed character - BAS
|
||
return
|
||
|
||
|
||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||
|
||
|
||
FCB_TO_ASCZ: ; Convert DS:SI to ASCIZ ES:DI
|
||
MOV CX,8
|
||
|
||
MAINNAME:
|
||
LODSB
|
||
CMP AL,' '
|
||
JZ SKIPSPC
|
||
STOSB
|
||
|
||
SKIPSPC:
|
||
LOOP MAINNAME
|
||
LODSB
|
||
CMP AL,' '
|
||
JZ GOTNAME
|
||
MOV AH,AL
|
||
MOV AL,dot_chr
|
||
STOSB
|
||
XCHG AL,AH
|
||
STOSB
|
||
MOV CL,2
|
||
|
||
EXTNAME:
|
||
LODSB
|
||
CMP AL,' '
|
||
JZ GOTNAME
|
||
STOSB
|
||
LOOP EXTNAME
|
||
|
||
GOTNAME:
|
||
XOR AL,AL
|
||
STOSB
|
||
return
|
||
|
||
STRCOMP:
|
||
;
|
||
; Compare ASCIZ DS:SI with ES:DI.
|
||
; SI,DI destroyed.
|
||
;
|
||
CMPSB
|
||
retnz ; Strings not equal
|
||
cmp byte ptr [SI-1],0 ; Hit NUL terminator?
|
||
retz ; Yes, strings equal
|
||
jmp short STRCOMP ; Equal so far, keep going
|
||
|
||
|
||
CRPRINT:
|
||
PUSH AX
|
||
MOV AL,13
|
||
PUSH CX
|
||
PUSH DI
|
||
MOV DI,DX
|
||
MOV CX,-1
|
||
PUSH ES
|
||
PUSH DS
|
||
POP ES
|
||
|
||
REPNZ SCASB ; LOOK FOR TERMINATOR
|
||
mov byte ptr [di-1],0 ; nul terminate the string
|
||
POP ES
|
||
mov string_ptr_2,dx
|
||
mov dx,offset trangroup:string_buf_ptr
|
||
invoke std_printf
|
||
mov ds:byte ptr [di-1],13 ; now put the CR back
|
||
JC ERROR_OUTPUT
|
||
|
||
POP DI
|
||
POP CX
|
||
POP AX
|
||
|
||
return
|
||
|
||
ERROR_OUTPUT:
|
||
PUSH CS
|
||
POP DS
|
||
ASSUME DS:TRANGROUP
|
||
MOV ES,[RESSEG]
|
||
ASSUME ES:RESGROUP
|
||
|
||
MOV DX,OFFSET TRANGROUP:NOSPACE_ptr
|
||
CMP [PIPEFLAG],0
|
||
JZ GO_TO_ERROR
|
||
|
||
invoke PipeOff
|
||
MOV DX,OFFSET TRANGROUP:PIPEEMES_ptr
|
||
GO_TO_ERROR:
|
||
JMP CERROR
|
||
|
||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||
|
||
PATHCHRCMP:
|
||
;---- Mod for path invocation ----
|
||
PUBLIC pathchrcmp
|
||
;----
|
||
|
||
push ax
|
||
mov ah,'/'
|
||
CMP [SWITCHAR],ah
|
||
JZ NOSLASHT
|
||
CMP AL,'/'
|
||
jz pccont
|
||
|
||
NOSLASHT:
|
||
CMP AL,'\'
|
||
pccont:
|
||
pop ax
|
||
|
||
return
|
||
|
||
;
|
||
; PATHCRUNCH -
|
||
;
|
||
; ENTRY FCB (in PSP) contains drive # to crunch on
|
||
; PathPos = ptr to string with pathname in it
|
||
; PathCnt = length of string
|
||
;
|
||
; EXIT PathPos = ptr after pathname (w/ NULL) in string
|
||
; PathCnt = length left in string
|
||
; DestIsDir = nonzero if pathname delimiter char's found in pathname
|
||
; DestInfo<bit1> = set if wildcard char's found in pathname
|
||
; If path crunched successfully,
|
||
; CY = clear
|
||
; Current directory is changed to directory in pathname
|
||
; UserDir1 contains previous directory for use by RestUDir
|
||
; RestDir = nonzero to flag later restoration of user's dir
|
||
; DestTail = ptr to beginning of filename
|
||
; If filename found in pathname,
|
||
; ZR = clear
|
||
; FCB filename fields contain filename
|
||
; If filename not found (pure directory path),
|
||
; ZR = set
|
||
; FCB filename fields are wildcarded with ?'s
|
||
; If pathcrunch failed (no ChDir's worked),
|
||
; CY = set
|
||
; Msg_Numb = extended error code
|
||
;
|
||
; NOTE DIR asks PathCrunch to forego parsing the filename into the
|
||
; FCB by setting DirFlag. In this case, the FCB is returned
|
||
; with the filename wildcarded.
|
||
;
|
||
PATHCRUNCH:
|
||
mov [msg_numb],0 ;AN022; Set up message flag
|
||
MOV DL,DS:[FCB] ; DL = drive # (1 = A)
|
||
CALL SAVUDIR ; save current directory in UserDir1
|
||
jc pcrunch_cderrJ ;AN022; if error on current dir - report
|
||
|
||
invoke SETPATH ; scan past switches, whitespace
|
||
|
||
; DX = ptr to pathname, NULL-terminated
|
||
; PathPos = ptr to byte after NULL at end of pathname
|
||
|
||
TEST [DESTINFO],2 ; test if wildcards (? or *) seen
|
||
JNZ TRYPEEL ; wildcard seen, peel filename
|
||
|
||
MOV AH,CHDIR ; AH = DOS ChDir function code
|
||
INT 21h ; call DOS
|
||
jnc chdir_worked ;AN022; no error - continue
|
||
|
||
invoke get_ext_error_number ;AN022; get the extended error
|
||
cmp ax,error_path_not_found ;AN022; if path not found
|
||
jz trypeel ;AC022; keep trying
|
||
cmp ax,error_access_denied ;AN022; if access denied
|
||
jz trypeel ;AC022; keep trying
|
||
mov [msg_numb],ax ;AN022; set up message flag
|
||
jmp peelfail ;AN022; exit with other error
|
||
|
||
chdir_worked:
|
||
invoke SETREST1 ; set 'Restore Directory' flag true
|
||
MOV AL,'?' ; if pure dir, wildcard filename in FCB
|
||
MOV DI,5DH
|
||
MOV CX,11
|
||
REP STOSB
|
||
XOR AL,AL ; return carry clear, zero set
|
||
return
|
||
|
||
pcrunch_cderrj: ;AN022; need this for long jmp
|
||
jmp pcrunch_cderr ;AN022;
|
||
|
||
TRYPEEL:
|
||
MOV SI,[PATHPOS]
|
||
DEC SI ; SI = ptr to NULL at end of pathname
|
||
MOV AL,[SI-1] ; AL = last char of pathname
|
||
|
||
CMP [KPARSE],0
|
||
JNZ DELSTRT ; Last char is second KANJI byte, might be '\'
|
||
|
||
CALL PATHCHRCMP
|
||
JZ PEELFAIL ; Trailing '/'
|
||
|
||
DELSTRT:
|
||
MOV CX,SI ; CX = ptr to NULL at end of pathname
|
||
MOV SI,DX ; SI = ptr to start of pathname
|
||
PUSH DX ; save ptr to pathname
|
||
DELLOOP:
|
||
CMP SI,CX
|
||
JZ GOTDELE ; no char's left, we have what we have
|
||
LODSB ; AL = next char of pathname
|
||
invoke TESTKANJ
|
||
JZ NOTKANJ8 ; not Kanji, move along
|
||
INC SI
|
||
JMP DELLOOP
|
||
|
||
NOTKANJ8:
|
||
CALL PATHCHRCMP
|
||
JNZ DELLOOP ; not a path delimiter, keep looking
|
||
MOV DX,SI
|
||
DEC DX ; DX = ptr to last delimiter found
|
||
JMP DELLOOP ; go look for more
|
||
|
||
GOTDELE:
|
||
MOV SI,DX ; SI = ptr to pathname or last delim
|
||
POP DX ; DX = ptr to pathname
|
||
CMP SI,DX
|
||
JZ BADRET ; didn't find path delim
|
||
MOV CX,SI ; CX = ptr to last path delimiter
|
||
MOV SI,DX ; SI = ptr to pathname
|
||
|
||
DELLOOP2: ; Set value of KPARSE
|
||
CMP SI,CX
|
||
JZ TRYCD ; roll up till SI meets CX
|
||
MOV [KPARSE],0
|
||
LODSB
|
||
INVOKE TESTKANJ
|
||
JZ DELLOOP2
|
||
INC SI
|
||
INC [KPARSE]
|
||
JMP DELLOOP2
|
||
|
||
TRYCD:
|
||
push ax
|
||
mov al,dot_chr ; AL = '.'
|
||
CMP BYTE PTR [SI+1],al ; check for '.' after path delim
|
||
;M019; allow continuation if '. ' or
|
||
;M019; '..' is not found.
|
||
jnz @F ;M019; '.' not found
|
||
cmp BYTE PTR [SI+2],al ;M019; check for '..'
|
||
jz @F ;M019; found '..'
|
||
cmp BYTE PTR [SI+2],0 ;M019; check for '. ' (null terminated)
|
||
@@: pop ax
|
||
JZ PEELFAIL ; if . or .., pure cd should have worked
|
||
mov al,[si-1]
|
||
CMP al,':' ; Special case d:\file
|
||
JZ BADRET
|
||
|
||
CMP [KPARSE],0
|
||
JNZ NOTDOUBLESL ; Last char is second KANJI byte, might be '\'
|
||
|
||
CALL PATHCHRCMP
|
||
JNZ NOTDOUBLESL
|
||
PEELFAIL:
|
||
STC ; //
|
||
return
|
||
NOTDOUBLESL:
|
||
MOV BYTE PTR [SI],0
|
||
MOV AH,CHDIR
|
||
INT 21h
|
||
JNC CDSUCC
|
||
pcrunch_cderr:
|
||
invoke get_ext_error_number ;AN022; get the extended error
|
||
mov [msg_numb],ax ;AN022; set up message flag
|
||
or si,si ;AN022; set up zero flag to not zero
|
||
stc ;AN022; set up carry flag
|
||
return
|
||
|
||
BADRET:
|
||
MOV AL,[SI]
|
||
CALL PATHCHRCMP ; Special case 'DIRCHAR'file
|
||
STC
|
||
retnz
|
||
XOR BL,BL
|
||
XCHG BL,[SI+1]
|
||
MOV AH,CHDIR
|
||
INT 21h
|
||
jc pcrunch_cderr ;AN022; go to error exit
|
||
MOV [SI+1],BL
|
||
CDSUCC:
|
||
invoke SETREST1
|
||
INC SI ; Reset zero
|
||
MOV [DESTTAIL],SI
|
||
pushf ;AN015; save flags
|
||
cmp dirflag,-1 ;AN015; don't do parse if in DIR
|
||
jz pcrunch_end ;AN015;
|
||
MOV DI,FCB
|
||
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 02H ; Parse with default drive
|
||
INT 21h
|
||
pcrunch_end:
|
||
popf ;AN015; get flags back
|
||
return
|
||
|
||
trancode ends
|
||
end
|
||
|