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