Leaked source code of windows server 2003
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

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