	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
