You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
711 lines
18 KiB
711 lines
18 KiB
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
|
|
|