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.
590 lines
15 KiB
590 lines
15 KiB
page ,132
|
|
; SCCSID = @(#)tucode.asm 4.2 85/05/31
|
|
; SCCSID = @(#)tucode.asm 4.2 85/05/31
|
|
Title COMMAND Language midifiable Code Transient
|
|
;/*
|
|
; * Microsoft Confidential
|
|
; * Copyright (C) Microsoft Corporation 1991
|
|
; * All Rights Reserved.
|
|
; */
|
|
|
|
|
|
.xlist
|
|
.xcref
|
|
include dossym.inc
|
|
include syscall.inc
|
|
include comsw.asm
|
|
include comseg.asm
|
|
include comequ.asm
|
|
.list
|
|
.cref
|
|
|
|
|
|
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
|
EXTRN ECHOFLAG:BYTE
|
|
DATARES ENDS
|
|
|
|
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
|
EXTRN BAD_ON_OFF_ptr:word
|
|
EXTRN ctrlcmes_ptr:word
|
|
EXTRN DEL_Y_N_PTR:WORD
|
|
EXTRN ECHOMES_ptr:word
|
|
EXTRN extend_buf_ptr:word ;AC000;
|
|
EXTRN offmes_ptr:word
|
|
EXTRN onmes_ptr:word
|
|
EXTRN PARSE_BREAK:BYTE ;AN000;
|
|
EXTRN promptdat_moday:word ;AC000;
|
|
EXTRN promptdat_ptr:word ;AC000;
|
|
EXTRN promptdat_yr:word ;AC000;
|
|
EXTRN string_buf_ptr:word
|
|
EXTRN SUREMES_ptr:word
|
|
EXTRN VERIMES_ptr:BYTE
|
|
EXTRN WeekTab:word
|
|
TRANDATA ENDS
|
|
|
|
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
|
EXTRN arg_buf:byte
|
|
EXTRN BWDBUF:BYTE
|
|
EXTRN DEST:BYTE
|
|
EXTRN destdir:byte
|
|
EXTRN dirchar:byte
|
|
EXTRN PARSE1_CODE:BYTE ;AN000;
|
|
EXTRN RESSEG:WORD
|
|
EXTRN string_ptr_2:word
|
|
|
|
TRANSPACE ENDS
|
|
|
|
TRANCODE SEGMENT PUBLIC BYTE
|
|
|
|
EXTRN CERROR:NEAR
|
|
EXTRN CRLF2:NEAR
|
|
EXTRN extend_setup:near ;AN022;
|
|
|
|
PUBLIC CNTRLC
|
|
PUBLIC ECHO
|
|
PUBLIC GetDate
|
|
PUBLIC NOTEST2
|
|
PUBLIC PRINT_DATE
|
|
PUBLIC SLASHP_ERASE ;AN000;
|
|
PUBLIC VERIFY
|
|
|
|
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
|
|
|
|
; ****************************************************************
|
|
; *
|
|
; * ROUTINE: NOTEST2 - execution of DEL/ERASE command
|
|
; *
|
|
; * FUNCTION: Delete files based on user parsed input. Prompt
|
|
; * user for Y/N if necessary. If an error occurs,
|
|
; * set up an error message and go to CERROR.
|
|
; *
|
|
; * INPUT: FCB at 5ch set up with filename(s) entered
|
|
; * Current directory set to entered directory
|
|
; *
|
|
; * OUTPUT: none
|
|
; *
|
|
; ****************************************************************
|
|
;
|
|
; ARE YOU SURE prompt when deleting *.*
|
|
|
|
NOTEST2:
|
|
MOV CX,11
|
|
MOV SI,FCB+1
|
|
|
|
AMBSPEC:
|
|
LODSB
|
|
CMP AL,'?'
|
|
JNZ ALLFIL
|
|
LOOP AMBSPEC
|
|
|
|
ALLFIL:
|
|
CMP CX,0
|
|
JNZ NOPRMPT
|
|
|
|
ASKAGN:
|
|
MOV DX,OFFSET TRANGROUP:SUREMES_ptr ; "Are you sure (Y/N)?"
|
|
invoke std_printf
|
|
MOV SI,80H
|
|
MOV DX,SI
|
|
MOV WORD PTR [SI],120 ; zero length
|
|
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_STRING_INPUT
|
|
INT 21H
|
|
LODSW
|
|
OR AH,AH
|
|
JZ ASKAGN
|
|
INVOKE SCANOFF
|
|
call char_in_xlat ;G Convert to upper case
|
|
retc ;AN000; return if function not supported
|
|
CMP AL,CAPITAL_N ;G
|
|
retz
|
|
CMP AL,CAPITAL_Y ;G
|
|
PUSHF
|
|
CALL CRLF2
|
|
POPF
|
|
JNZ ASKAGN
|
|
|
|
NOPRMPT:
|
|
MOV AH,FCB_DELETE
|
|
MOV DX,FCB
|
|
INT 21H
|
|
INC AL
|
|
jz eraerr
|
|
invoke RESTUDIR
|
|
ret ; If no error, return
|
|
|
|
eraerr:
|
|
invoke set_ext_error_msg ;AN022; set up the extended error
|
|
push dx ;AN022; save message
|
|
invoke RESTUDIR
|
|
pop dx ;AN022; restore message
|
|
|
|
cmp word ptr extend_buf_ptr,error_no_more_files ;AN022; convert no more files to
|
|
jnz cerrorj2 ;AN022; file not found
|
|
mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block
|
|
|
|
cerrorj2:
|
|
jmp cerror
|
|
|
|
|
|
; ****************************************************************
|
|
; *
|
|
; * ROUTINE: SLASHP_ERASE - execution of DEL/ERASE /P
|
|
; *
|
|
; * FUNCTION: Delete files based on user parsed input. Prompt
|
|
; * user for Y/N where necessary. If an error occurs
|
|
; * set up and error message and transfer control
|
|
; * to CERROR.
|
|
; *
|
|
; * INPUT: FCB at 5ch set up with filename(s) entered
|
|
; * Current directory set to entered directory
|
|
; *
|
|
; * OUTPUT: none
|
|
; *
|
|
; ****************************************************************
|
|
|
|
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
|
|
|
|
SLASHP_ERASE: ;AN000; entry point
|
|
invoke build_dir_string ;AN000; set up current directory string for output
|
|
mov ah,Set_DMA ;AN000; issue set dta int 21h
|
|
mov dx,offset trangroup:destdir ;AN000; use Destdir for target
|
|
int 21H ;AN000;
|
|
mov ah,Dir_Search_First ;AN000; do dir search first int 21h
|
|
mov dx,FCB ;AN000; use FCB at 5Ch for target
|
|
int 21H ;AN000;
|
|
inc al ;AN000; did an error occur
|
|
jz eraerr ;AN022; go to error exit
|
|
|
|
delete_prompt_loop: ;AN000;
|
|
mov si,offset trangroup:destdir+1 ;AN000; set up FCB as source
|
|
mov di,offset trangroup:dest ;AN000; set up dest as target
|
|
mov al,dirchar ;AN000; store a "\" in the first char
|
|
stosb ;AN000; of DEST
|
|
invoke fcb_to_ascz ;AN000; convert filename from FCB to ASCIIZ string
|
|
|
|
slashp_askagn: ;AN000;
|
|
call crlf2 ;AN000; print out carriage return, line feed
|
|
mov dx,offset trangroup:bwdbuf ;AN000; print out current directory string
|
|
mov bx,dx ;AN000; get string pointer in bx
|
|
cmp byte ptr [bx+3],end_of_line_out ;AN000; see if only D:\,0
|
|
jnz not_del_root ;AN000; no continue
|
|
mov byte ptr [bx+2],end_of_line_out ;AN000; yes, get rid of \
|
|
|
|
Not_del_root: ;AN000;
|
|
mov string_ptr_2,dx ;AN000;
|
|
mov dx,offset trangroup:string_buf_ptr ;AN000;
|
|
invoke std_printf ;AN000;
|
|
mov dx,offset trangroup:dest ;AN000; print out file name string
|
|
mov string_ptr_2,dx ;AN000;
|
|
mov dx,offset trangroup:string_buf_ptr ;AN000;
|
|
invoke std_printf ;AN000;
|
|
mov dx,offset trangroup:Del_Y_N_Ptr ;AN000; issue ", Delete (Y/N)?" message
|
|
invoke std_printf ;AN000;
|
|
;;M029 mov si,80H ;AN000; set up buffer for input
|
|
;;M029 mov dx,si ;AN000;
|
|
;;M029 mov word ptr [si],combuflen ;AN000;
|
|
;;M029 mov ax,(std_con_input_flush shl 8) or std_con_string_input ;AN000;
|
|
;;M029 int 21h ;AN000; get input from the user
|
|
;;M029 lodsw ;AN000;
|
|
;;M029 or ah,ah ;AN000; was a character entered?
|
|
;;M029 jz slashp_askagn ;AN000; no - ask again
|
|
;;M029 invoke scanoff ;AN000; scan off leading delimiters
|
|
|
|
; Get a single character input.
|
|
|
|
mov ax,(std_con_input_flush shl 8) or std_con_input ;M029
|
|
int 21h ;M029
|
|
|
|
call char_in_xlat ;AN000; yes - upper case it
|
|
retc ;AN000; return if function not supported
|
|
cmp al,capital_n ;AN000; was it no?
|
|
jz next_del_file ;AN000; yes - don't delete file
|
|
cmp al,capital_y ;AN000; was it yes?
|
|
jz delete_this_file ;AN000; yes - delete the file
|
|
jmp short slashp_askagn ;AN000; it was neither - ask again
|
|
|
|
delete_this_file: ;AN000;
|
|
mov ah,fcb_delete ;AN000; delete the file
|
|
mov dx,offset trangroup:destdir ;AN000; use Destdir for target
|
|
int 21h ;AN000;
|
|
inc al ;AN000; did an error occur?
|
|
jnz next_del_file ;AN000; no - get next file
|
|
;
|
|
;M041; Begin changes
|
|
; We got an error deleting the file. If this is access denied, we can go on
|
|
;to the next file after printing an error message.
|
|
;
|
|
invoke Get_ext_error_number ;see what error we got
|
|
cmp ax,error_access_denied ;is it access denied?
|
|
jne stop_del ;no, some other error
|
|
invoke CrLf2 ;print a CR-LF
|
|
invoke set_ext_error_msg ;error message
|
|
invoke std_eprintf ;"Access denied"
|
|
jmp short next_del_file ;try next file
|
|
stop_del:
|
|
;
|
|
;M041; End changes
|
|
;
|
|
jmp eraerr ;AN022; go to error exit - need long jmp
|
|
|
|
next_del_file: ;AN000;
|
|
;
|
|
; M050 - begin
|
|
; Norton Utilities 5.0 has a bug. DiskMon when invoked
|
|
; with /protect+ and /light+ makes it intercept all
|
|
; deletes. This hook does not save and restore the DTA correctly.
|
|
; They save the DWORD in a WORD by mistake! They save both the
|
|
; segment and the offset in the SAME variable (WORD)!!!
|
|
;
|
|
mov ah,Set_DMA
|
|
mov dx,offset trangroup:destdir
|
|
int 21H
|
|
;
|
|
; M050 - end
|
|
|
|
mov ah,dir_search_next ;AN000; search for another file
|
|
mov dx,FCB ;AN000;
|
|
int 21h ;AN000;
|
|
inc al ;AN000; was a file found?
|
|
jz slash_p_exit ;AN000; no - exit
|
|
jmp delete_prompt_loop ;AN000; yes - continue (need long jump)
|
|
|
|
slash_p_exit:
|
|
invoke get_ext_error_number ;AN022; get the extended error number
|
|
cmp ax,error_no_more_files ;AN022; was error file not found?
|
|
jz good_erase_exit ;AN022; yes - clean exit
|
|
jmp extend_setup ;AN022; go issue error message
|
|
|
|
good_erase_exit:
|
|
invoke restudir ;AN000; we're finished - restore user's dir
|
|
call crlf2 ;AN000; print out carriage return, line feed
|
|
ret ;AN000; exit
|
|
|
|
|
|
;************************************************
|
|
; ECHO, BREAK, and VERIFY commands. Check for "ON" and "OFF"
|
|
|
|
break Echo
|
|
|
|
assume ds:trangroup,es:trangroup
|
|
|
|
ECHO:
|
|
CALL ON_OFF
|
|
JC DOEMES
|
|
MOV DS,[RESSEG]
|
|
ASSUME DS:RESGROUP
|
|
JNZ ECH_OFF
|
|
OR [ECHOFLAG],1
|
|
RET
|
|
ECH_OFF:
|
|
AND [ECHOFLAG],NOT 1
|
|
RET
|
|
|
|
|
|
CERRORJ:
|
|
JMP CERROR
|
|
|
|
;
|
|
; There was no discrenable ON or OFF after the ECHO. If there is nothing but
|
|
; delimiters on the command line, we issue the ECHO is ON/OFF message.
|
|
;
|
|
|
|
ASSUME DS:TRANGROUP
|
|
|
|
DOEMES:
|
|
cmp cl,0 ;AC000; was anything on the line?
|
|
jz PEcho ; just display current state.
|
|
MOV DX,82H ; Skip one char after "ECHO"
|
|
invoke CRPRINT
|
|
JMP CRLF2
|
|
|
|
PECHO:
|
|
MOV DS,[RESSEG]
|
|
ASSUME DS:RESGROUP
|
|
MOV BL,[ECHOFLAG]
|
|
PUSH CS
|
|
POP DS
|
|
ASSUME DS:TRANGROUP
|
|
AND BL,1
|
|
MOV DX,OFFSET TRANGROUP:ECHOMES_ptr
|
|
JMP SHORT PYN
|
|
|
|
break Break
|
|
assume ds:trangroup,es:trangroup
|
|
|
|
CNTRLC:
|
|
CALL ON_OFF
|
|
MOV AX,(SET_CTRL_C_TRAPPING SHL 8) OR 1
|
|
JC PCNTRLC
|
|
JNZ CNTRLC_OFF
|
|
MOV DL,1
|
|
INT 21H ; Set ^C
|
|
RET
|
|
|
|
CNTRLC_OFF:
|
|
XOR DL,DL
|
|
INT 21H ; Turn off ^C check
|
|
RET
|
|
|
|
PCNTRLC:
|
|
CMP CL,0 ;AC000; rest of line blank?
|
|
JNZ CERRORJ ; no, oops!
|
|
|
|
pccont:
|
|
XOR AL,AL
|
|
INT 21H
|
|
MOV BL,DL
|
|
MOV DX,OFFSET TRANGROUP:CTRLCMES_ptr
|
|
|
|
PYN:
|
|
mov si,offset trangroup:onmes_ptr ;AC000; get ON pointer
|
|
OR BL,BL
|
|
JNZ PRINTVAL
|
|
mov si,offset trangroup:offmes_ptr ;AC000; get OFF pointer
|
|
|
|
PRINTVAL:
|
|
push dx ;AN000; save offset of message block
|
|
mov bx,dx ;AN000; save offset value
|
|
lodsw ;AN000; get message number of on or off
|
|
mov dh,util_msg_class ;AN000; this is a utility message
|
|
invoke Tsysgetmsg ;AN000; get the address of the message
|
|
add bx,ptr_off_pos ;AN000; point to offset of ON/OFF
|
|
mov word ptr [bx],si ;AN000; put the offset in the message block
|
|
pop dx ;AN000; get message back
|
|
invoke std_printf ;AC000; go print message
|
|
mov word ptr [bx],0 ;AN000; zero out message pointer
|
|
|
|
ret ;AN000; exit
|
|
|
|
break Verify
|
|
assume ds:trangroup,es:trangroup
|
|
|
|
VERIFY:
|
|
CALL ON_OFF
|
|
MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1
|
|
JC PVERIFY
|
|
JNZ VER_OFF
|
|
INT 21H ; Set verify
|
|
RET
|
|
|
|
VER_OFF:
|
|
DEC AL
|
|
INT 21H ; Turn off verify after write
|
|
RET
|
|
|
|
PVERIFY:
|
|
CMP CL,0 ;AC000; is rest of line blank?
|
|
JNZ CERRORJ ; nope...
|
|
MOV AH,GET_VERIFY_ON_WRITE
|
|
INT 21H
|
|
MOV BL,AL
|
|
MOV DX,OFFSET TRANGROUP:VERIMES_ptr
|
|
JMP PYN
|
|
|
|
; ****************************************************************
|
|
; *
|
|
; * ROUTINE: ON_OFF
|
|
; *
|
|
; * FUNCTION: Parse the command line for an optional ON or
|
|
; * OFF string for the BREAK, VERIFY, and ECHO
|
|
; * routines.
|
|
; *
|
|
; * INPUT: command line at offset 81H
|
|
; * PARSE_BREAK control block
|
|
; *
|
|
; * OUTPUT: If carry is clear
|
|
; * If ON is found
|
|
; * Zero flag set
|
|
; * If OFF is found
|
|
; * Zero flag clear
|
|
; * If carry set
|
|
; * If nothing on command line
|
|
; * CL set to zero
|
|
; * If error
|
|
; * CL contains error value from parse
|
|
; *
|
|
; ****************************************************************
|
|
|
|
assume ds:trangroup,es:trangroup
|
|
|
|
ON_OFF:
|
|
MOV SI,81h
|
|
|
|
scan_on_off: ;AN032; scan off leading blanks & equal
|
|
lodsb ;AN032; get a char
|
|
cmp al,blank ;AN032; if whitespace
|
|
jz scan_on_off ;AN032; keep scanning
|
|
cmp al,tab_chr ;AN032; if tab
|
|
jz scan_on_off ;AN032; keep scanning
|
|
cmp al,equal_chr ;AN032; if equal char
|
|
jz parse_on_off ;AN032; start parsing
|
|
dec si ;AN032; if none of above - back up
|
|
|
|
parse_on_off: ;AN032; and start parsing
|
|
mov di,offset trangroup:parse_break ;AN000; Get adderss of PARSE_BREAK
|
|
xor cx,cx ;AN000; clear cx,dx
|
|
xor dx,dx ;AN000;
|
|
invoke cmd_parse ;AC000; call parser
|
|
cmp ax,end_of_line ;AC000; are we at end of line?
|
|
jz BADONF ;AC000; yes, return error
|
|
cmp ax,result_no_error ;AN000; did an error occur
|
|
jz on_off_there ;AN000; no - continue
|
|
mov cx,ax ;AN000; yes - set cl to error code
|
|
jmp short BADONF ;AN000; return error
|
|
|
|
on_off_there:
|
|
cmp parse1_code,-1 ;AN014; was a valid positional present?
|
|
jnz good_on_off ;AN014; yes - continue
|
|
mov cx,badparm_ptr ;AN014; something other than ON/OFF
|
|
jmp short BADONF ;AN014; return error
|
|
|
|
good_on_off: ;AN014;
|
|
xor ax,ax ;AC000; set up return code for
|
|
or al,parse1_code ;AC000; ON or OFF in AX
|
|
pushf ;AN000; save flags
|
|
mov di,offset trangroup:parse_break ;AN000; Get adderss of PARSE_BREAK
|
|
xor dx,dx ;AN000;
|
|
invoke cmd_parse ;AN000; call parser
|
|
cmp ax,end_of_line ;AN000; are we at end of line?
|
|
jnz BADONF_flags ;AN000; NO, return error
|
|
popf ;AN000; restore flags
|
|
clc ;AC000; no error
|
|
jmp short on_off_end ;AN000; return to caller
|
|
|
|
BADONF_flags:
|
|
mov cx,ax
|
|
popf
|
|
|
|
;
|
|
; No discernable ON or OFF has been found. Put an error message pointer in DX
|
|
; and return the error
|
|
;
|
|
BADONF:
|
|
MOV DX,OFFSET TRANGROUP:BAD_ON_OFF_ptr
|
|
STC
|
|
|
|
ON_OFF_END:
|
|
|
|
RET
|
|
|
|
|
|
|
|
;*************************************************************************
|
|
; print date
|
|
|
|
PRINT_DATE:
|
|
PUSH ES
|
|
PUSH DI
|
|
PUSH CS
|
|
POP ES
|
|
CALL GetDate ; get date
|
|
xchg dh,dl ;AN000; switch month & day
|
|
mov promptDat_yr,cx ;AC000; put year into message control block
|
|
mov promptDat_moday,dx ;AC000; put month and day into message control block
|
|
mov dx,offset trangroup:promptDat_ptr ;AC000; set up message for output
|
|
invoke std_printf
|
|
;AD061; mov promptDat_yr,0 ;AC000; reset year, month and day
|
|
;AD061; mov promptDat_moday,0 ;AC000; pointers in control block
|
|
POP DI ;AC000; restore di,es
|
|
POP ES ;AC000;
|
|
return
|
|
;
|
|
; Do GET DATE system call and set up 3 character day of week in ARG_BUF
|
|
; for output. Date will be returned in CX,DX.
|
|
;
|
|
|
|
GetDate:
|
|
mov di,offset trangroup:arg_buf ;AC000; target for day of week
|
|
MOV AH,GET_DATE ;AC000; get current date
|
|
INT 21h ;AC000; Get date in CX:DX
|
|
CBW ;AC000;
|
|
|
|
push cx ;AN000; save date returned in
|
|
push dx ;AN000; CX:DX
|
|
MOV SI,AX
|
|
IFNDEF DBCS
|
|
SHL SI,1
|
|
ADD SI,AX ; SI=AX*3
|
|
ELSE
|
|
ifdef JAPAN ; MSKK01 07/14/89
|
|
shl si,1
|
|
shl si,1 ; SI=AX*4
|
|
endif
|
|
IFDEF TAIWAN
|
|
SHL SI,1
|
|
ADD SI,AX
|
|
SHL SI,1 ; SI=AX*6
|
|
ENDIF
|
|
ifdef KOREA
|
|
shl si,1
|
|
endif
|
|
ENDIF
|
|
mov cx,si ;AN000; save si
|
|
mov ax,weektab ;AN000; get message number of weektab
|
|
mov dh,util_msg_class ;AN000; this is a utility message
|
|
push di ;AN000; save argument buffer
|
|
invoke Tsysgetmsg ;AN000; get the address of the message
|
|
pop di ;AN000; retrieve argument buffer
|
|
add si,cx ;AC000; get day of week
|
|
IFNDEF DBCS
|
|
MOV CX,3
|
|
ELSE
|
|
ifdef JAPAN ; MSKK01 07/14/89
|
|
mov cx,4
|
|
endif
|
|
IFDEF TAIWAN
|
|
MOV CX,6
|
|
ENDIF
|
|
ifdef KOREA
|
|
mov cx,2 ; MSCH 90/9/6
|
|
endif
|
|
ENDIF
|
|
REP MOVSB
|
|
mov al,end_of_line_out ;AC000; terminate the string
|
|
stosb
|
|
pop dx ;AN000; get back date
|
|
pop cx ;AN000;
|
|
|
|
return
|
|
;g
|
|
;g This routine determines whether the character in AL is a
|
|
;g Yes or No character. On return, if AL=0, the character is
|
|
;g No, if AL=1, the character is Yes.
|
|
;g
|
|
|
|
assume ds:trangroup
|
|
|
|
char_in_xlat proc near
|
|
|
|
mov dl,al ;AC000; get character into DX
|
|
xor dh,dh ;AC000;
|
|
mov ax,(getextcntry SHL 8) + 35 ;AC000; Yes/No char call
|
|
int 21h ;AC000;
|
|
|
|
ret
|
|
|
|
char_in_xlat endp
|
|
|
|
TRANCODE ENDS
|
|
END
|
|
|