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.
 
 
 
 
 
 

646 lines
19 KiB

page ,132
; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22
; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22
TITLE PART5 COMMAND Transient routines.
;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1991
; * All Rights Reserved.
; */
.xlist
.xcref
include comsw.asm
include dossym.inc
include syscall.inc
include pdb.inc
include mult.inc
include comseg.asm
include comequ.asm
include cmdsvc.inc
.list
.cref
;;CODERES SEGMENT PUBLIC BYTE ;AC000;
;; EXTRN LODCOM1:NEAR
;;CODERES ENDS
DATARES SEGMENT PUBLIC BYTE ;AC000;
EXTRN crit_msg_off:word ;AC000;
EXTRN crit_msg_seg:word ;AC000;
EXTRN IO_SAVE:WORD
EXTRN OldTerm:DWORD
EXTRN PARENT:WORD
;AD060; EXTRN pars_msg_off:word ;AC000;
;AD060; EXTRN pars_msg_seg:word ;AC000;
EXTRN PERMCOM:BYTE ;AN045;
EXTRN RetCode:WORD
EXTRN SingleCom:word
extrn TrnLodCom1_Trap:far
DATARES ENDS
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
EXTRN ACRLF_PTR:WORD ;AN007;
EXTRN baddev_ptr:word
EXTRN CP_active_Ptr:word
EXTRN CP_not_all_Ptr:word
EXTRN CP_not_set_Ptr:word
EXTRN Extend_buf_ptr:word ;AN000;
EXTRN Extend_buf_sub:byte ;AN000;
EXTRN inv_code_page:word ;AC000;
EXTRN msg_disp_class:byte ;AN000;
EXTRN NLSFUNC_Ptr:word ;AC000;
EXTRN parse_chcp:byte ;AC000;
EXTRN parse_chdir:byte ;AC000;
EXTRN parse_ctty:byte ;AC000;
EXTRN string_buf_ptr:word ;AC000;
extrn NoCntry_Ptr:word ;M045
TRANDATA ENDS
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
EXTRN COMBUF:BYTE
EXTRN parse_last:word ;AN018;
EXTRN parse1_addr:dword ;AC000;
EXTRN parse1_type:byte ;AC000;
EXTRN RESSEG:WORD
EXTRN srcbuf:byte
EXTRN srcxname:byte ;AC000;
EXTRN string_ptr_2:word
EXTRN system_cpage:word
EXTRN TRAN_TPA:WORD
TRANSPACE ENDS
TRANCODE SEGMENT PUBLIC BYTE
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
;---------------
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
EXTRN arg:byte ; the arg structure!
TRANSPACE ENDS
;---------------
EXTRN cerror:near
extrn TCommand:near
PUBLIC $exit
PUBLIC chcp
PUBLIC ctty
PUBLIC parse_check_eol ;AN000;
PUBLIC parse_with_msg ;AN018;
PUBLIC setup_parse_error_msg ;AN018;
PUBLIC truename ;AN000;
break Ctty
assume ds:trangroup,es:trangroup
; ****************************************************************
; *
; * ROUTINE: CTTY - Change console
; *
; * SYNTAX: CTTY device
; *
; * FUNCTION: If a valid console device is specified, CTTY will
; * duplicate the device handle to STDIN, STDOUT and
; * STDERR. This routine returns to LODCOM1.
; *
; * INPUT: command line at offset 81H
; *
; * OUTPUT: none
; *
; ****************************************************************
CTTY:
push ds ;AN000; Get local ES
pop es ;AN000;
mov si,81H ;AC000; Get command argument for CTTY
mov di,offset trangroup:parse_ctty ;AC000; Get adderss of PARSE_CTTY
xor cx,cx ;AC000; clear cx,dx
xor dx,dx ;AC000;
invoke cmd_parse ;AC000; call parser
cmp ax,end_of_line ;AN000; are we at end of line?
jz ctty_error ;AN000; yes - error
cmp ax,result_no_error ;AN000; did an error occur
jnz ctty_error ;AN000; YES -ERROR
push si ;AN000; save position in line
lds si,parse1_addr ;AN000; get address of filespec
mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf
ctty_move_filename: ;AN000; put filespec in srcbuf
lodsb ;AN000; get a char from buffer
stosb ;AN000; store in srcbuf
cmp al,end_of_line_out ;AN000; it char a terminator?
jnz ctty_move_filename ;AN000; no - keep moving
pop si ;AN000; get line position back
mov di,offset trangroup:parse_ctty ;AC000; Get adderss of PARSE_CTTY
ifndef NEC_98
call parse_check_eol ;AN000; are we at end of line?
else ;NEC_98
; call parse_check_eol ;AN000; are we at end of line? ; NEC01 91/07/31 Del
xor dx,dx ;AN000; ; NEC01 91/07/31
mov [parse_last],si ;AN018; save start of parameter ; NEC01 91/07/31
invoke cmd_parse ;AN000; call parser ; NEC01 91/07/31
cmp al,end_of_line ;AN000; Are we at end of line? ; NEC01 91/07/31
endif ;NEC_98
jz nocolon ;AN000; yes - continue
ctty_error:
jmp short isbaddev ;AC000; yes - exit
nocolon:
mov dx,offset trangroup:srcbuf ;AN000; get address of srcbuf
MOV AX,(OPEN SHL 8) OR 2 ; Read and write
INT 21h ; Open new device
JC ISBADDEV
MOV BX,AX
MOV AX,IOCTL SHL 8
INT 21h
TEST DL,80H
JNZ DEVISOK
CLOSEDEV: ;AN007;
MOV AH,CLOSE ; Close initial handle
INT 21h
ISBADDEV:
MOV DX,OFFSET TRANGROUP:BADDEV_ptr
invoke std_printf
JMP SHORT RESRET
DEVISOK:
push dx ;AN007; save device info
mov ax,acrlf_ptr ;AN021; get message number for 0d, 0a
mov dh,util_msg_class ;AN021; this is a utility message
push bx ;AN021; save handle
invoke Tsysgetmsg ;AN021; get the address of the message
mov dx,si ;AN021; get address into dx
mov ax,(write shl 8) ;AN007; write to device
mov cx,2 ;AN007; write two bytes
int 21h ;AN007;
pop bx ;AN021; get back handle
pop dx ;AN007; get back device info
jc closedev ;AN007; if error, quit
XOR DH,DH
OR DL,3 ; Make sure has CON attributes
MOV AX,(IOCTL SHL 8) OR 1
INT 21h
PUSH BX ; Save handle
MOV CX,3
XOR BX,BX
ICLLOOP: ; Close basic handles
MOV AH,CLOSE
INT 21h
INC BX
LOOP ICLLOOP
POP BX ; Get handle
MOV AH,XDUP
INT 21h ; Dup it to 0
MOV AH,XDUP
INT 21h ; Dup to 1
MOV AH,XDUP
INT 21h ; Dup to 2
MOV AH,CLOSE ; Close initial handle
INT 21h
RESRET:
MOV DS,[RESSEG]
ASSUME DS:RESGROUP
PUSH DS
MOV AX,WORD PTR DS:[PDB_JFN_Table] ; Get new 0 and 1
MOV [IO_SAVE],AX
MOV AX,OFFSET DATARES:TrnLodCom1_Trap
PUSH AX
ZMMMM PROC FAR
RET ; Force header to be checked
ZMMMM ENDP
break Chcp
;****************************************************************
;*
;* ROUTINE: CHCP - Change code page internal command
;* (added DOS 3.30 07/21/86)
;*
;* SYNTAX: CHCP [xxx]
;* where xxx is a valid code page
;*
;* FUNCTION: If xxx is specified, CHCP will use INT 21H function
;* 6402H to set the code page to xxxx. If no parameters
;* are specified, CHCP will use INT 21H function 6401H
;* to get global code page and display it to the user.
;*
;* INPUT: command line at offset 81H
;*
;* OUTPUT: none
;*
;****************************************************************
NLSFUNC_installed equ 0ffh
set_global_cp equ 2
get_global_cp equ 1
assume ds:trangroup,es:trangroup
CHCP:
push ds ;AN000; Get local ES
pop es ;AN000;
mov si,81H ;AC000; Get command argument for CHCP
mov di,offset trangroup:parse_chcp ;AN000; Get adderss of PARSE_CHCP
xor cx,cx ;AC000; clear cx,dx
xor dx,dx ;AC000;
call parse_with_msg ;AC018; call parser
cmp ax,end_of_line ;AN000; are we at end of line?
;; jnz setcp ;AC000; no go get number & set code page
jz getcp ;AC000; yes - no parm - get code page
setcp:
cmp ax,result_no_error ;AN000; did we have an error?
jne cp_error ;AC018; yes - go issue message
push cx ;AN000; save positional count
mov bx,offset trangroup:parse1_addr ;AN000; get number returned
mov cx,word ptr [bx] ;AN000; into cx
mov system_cpage,cx ;AN000; save user input number
pop cx ;AC000; restore positional count
mov di,offset trangroup:parse_chcp ;AN000; Get adderss of PARSE_CHCP
call parse_check_eol ;AN000; are we at end of line?
jnz cp_error ;AC000; no - exit
okset:
mov ah,NLSFUNC ;AN000; see if NLSFUNC installed
mov al,0 ;AN000;
int 2fh ;AN000;
cmp al,NLSFUNC_installed ;AN000;
jz got_NLS ;AN000; Yes - continue
mov dx,offset trangroup:NLSFUNC_ptr ;AN000; no - set up error message
jmp short cp_error ;AN000; error exit
got_NLS:
mov bx,system_cpage ;AN000; get user input code page
mov ah,getsetcdpg ;get/set global code page function
mov al,set_global_cp ;minor - set
int 21h
jnc chcp_return ;no error - exit
;
;added for p716
;
cmp ax,error_file_not_found ;p716 was the error file not found?
jnz chcp_other_error ;no - country.sys was found
mov ah,GetExtendedError ;p850 see if error is invalid data
xor bx,bx ; which is file was found but CP
int 21h ; information was not found.
cmp ax,error_invalid_data ;AC000; invalid code page
jnz no_countrysys ;no - use file not found
mov dx,offset trangroup:inv_code_page ;AN000; get message
jmp short cp_error ;AC000; error exit
no_countrysys:
;M045; mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
;M045; mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
;M045; mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block
mov dx,offset TRANGROUP:NoCntry_Ptr ;M045
jmp short cp_error ;AC000; error exit
chcp_other_error:
;
; end of p716
;
mov ah,GetExtendedError ;error - see what it is
xor bx,bx
int 21h
cmp ax,65 ;was it access denied?
jnz none_set ;no - assume all failed
mov dx,offset trangroup:cp_not_all_ptr ;set up message
jmp short cp_error ;AC000; error exit
none_set:
mov dx,offset trangroup:cp_not_set_ptr ;set up message
cp_error: ;AN000;
jmp cerror ;exit
getcp:
mov ah,getsetcdpg ;get/set global code page function
mov al,get_global_cp ;minor - get
int 21h
mov system_cpage,bx ;get active cp for output
mov dx,offset trangroup:cp_active_ptr
invoke std_printf ;print it out
chcp_return:
RET
break TRUENAME ;AN000;
; ****************************************************************
; *
; * ROUTINE: TRUENAME
; *
; * FUNCTION: Entry point for the internal TRUENAME command.
; * Parses the command line. If a path is found, set
; * SRCXNAME to path. If only a drive letter is
; * found, set SRCXNAME to the drive letter. If
; * no path is found, set the path of SRCXNAME to
; * dot (.) for current directory. Use the NAME
; * TRANSLATE system call to get the real name and
; * then display the real name. If an error occurs
; * issue an error message and transfer control to
; * CERROR.
; *
; * INPUT: command line at offset 81H
; *
; * OUTPUT: none
; *
; ****************************************************************
assume ds:trangroup,es:trangroup ;AN000;
TRUENAME: ;AN000; TRUENAME entry point
push ds ;AN000; Get local ES
pop es ;AN000;
mov si,81H ;AN000; Get command line
mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR
xor cx,cx ;AN000; clear cx,dx
xor dx,dx ;AN000;
call parse_with_msg ;AC018; call parser
mov di,offset trangroup:srcxname ;AN000; get address of srcxname
cmp ax,end_of_line ;AN000; are we at end of line?
je tn_eol ;AN000; yes - go process
cmp ax,result_no_error ;AN000; did we have an error?
jne tn_parse_error ;AN000; yes - go issue message
cmp parse1_type,result_drive ;AN000; was a drive entered?
je tn_drive ;AN000; yes - go process
jmp short tn_filespec ;AN000; nothing else - must be filespec
tn_eol: ;AN000; no parameters on line
mov ah,end_of_line_out ;AN000; set buffer to .
mov al,dot_chr ;AN000; for current dir
stosw ;AN000; store in srcxname
jmp short tn_doit ;AN000; go do command
tn_drive: ;AN000; a drive was entered
push si ;AN000; save position in line
mov si,offset trangroup:parse1_addr ;AN000; get address of drive
lodsb ;AN000; get the drive number
add al,"A"-1 ;AN000; convert it to char
stosb ;AN000; store it in srcxname
mov ax,dot_colon ;AN000; get colon and . and
stosw ;AN000; store in srcxname
mov al,end_of_line_out ;AN000; put a terminator char
stosb ;AN000;
pop si ;AN000; get line position back
jmp short tn_check_eol ;AN000; check to make sure eol
tn_filespec: ;AN000; a filespec was entered
push si ;AN000; save position in line
lds si,parse1_addr ;AN000; get address of filespec
tn_move_filename: ;AN000; put filespec in srcxname
lodsb ;AN000; get a char from buffer
stosb ;AN000; store in srcxname
cmp al,end_of_line_out ;AN000; it char a terminator?
jnz tn_move_filename ;AN000; no - keep moving
pop si ;AN000; get line position back
tn_check_eol: ;AN000; make sure no extra parms
mov di,offset trangroup:parse_chdir ;AN000; get address of parse_chdir
call parse_check_eol ;AN000; are we at end of line?
je tn_doit ;AN000; Yes - do the command
tn_parse_error: ;AN000; A parse error occurred
jmp cerror ;AN000; Go to error routine
tn_doit: ;AN000;
mov si,offset trangroup:srcxname ;AN000; set up srcxname as source
mov di,offset trangroup:combuf ;AN000; set up combuf as target (need big target)
mov ah,xnametrans ;AN000; do name translate call
int 21h ;AN000;
jnc tn_print_xname ;AN000; If no error - print result
invoke Set_ext_error_msg ;AN000; get extended message
mov string_ptr_2,offset trangroup:srcxname ;AN000; get address of failed string
mov Extend_buf_sub,one_subst ;AN000; put number of subst in control block
jmp cerror ;AN000; Go to error routine
tn_print_xname: ;AN000;
mov string_ptr_2,offset Trangroup:combuf ;AN000; Set up address of combuf
mov dx,offset trangroup:string_buf_ptr ;AN000; Set up address of print control block
invoke crlf2 ;AN000; print a crlf
invoke printf_crlf ;AN000; print it out
ret ;AN000;
break $Exit
assume ds:trangroup,es:trangroup
$EXIT:
push ds ;AN000; save data segment
mov ds,[resseg] ;AN000; get resident data segment
assume ds:resgroup ;AN000;
cmp [permcom],0 ;AN045; is this a permanent COMMAND?
jz free_com ;AN045; no - free everything
; We're a permanent command.
; Unless this is a singlecom (int 2Eh), don't deallocate transient.
cmp [singlecom],-1 ;M034
je no_reset ;M034 ;exit singlecom
; jmp TCommand ;permanent command, recycle
;Sudeepb 05-Jul-1991; Removed above jmp to terminate the top level
; command.com.
CMDSVC SVC_CMDEXITVDM ; Never returns
;AD060; mov ah,multdos ;AN000; reset parse message pointers
;AD060; mov al,message_2f ;AN000; call for message retriever
;AD060; mov dl,set_parse_msg ;AN000; set up parse message address
;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages
;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages
;AD060; int 2fh ;AN000; go set it
;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
;AD060; mov al,message_2f ;AN000; call for message retriever
free_com:
mov ax,(multdos shl 8 or message_2f);AN060; reset parse message pointers
mov dl,set_critical_msg ;AN000; set up critical error message address
mov di,crit_msg_off ;AN000; old offset of critical messages
mov es,crit_msg_seg ;AN000; old segment of critical messages
int 2fh ;AN000; go set it
no_reset: ;AN045;
pop ds ;AN000; restore local data segment
assume ds:trangroup ;AN000;
;
;M040
; Restore user directory if the restore flag is set. RestUDir1 checks for
;this, restores user dir if flag is set and resets the flag.
;
invoke RestUDir1 ;restore user dir if needed ;M040
MOV ES,[RESSEG]
assume es:resgroup
MOV AX,[PARENT]
MOV WORD PTR ES:[PDB_Parent_PID],AX
MOV AX,WORD PTR OldTerm
MOV WORD PTR ES:[PDB_Exit],AX
MOV AX,WORD PTR OldTerm+2
MOV WORD PTR ES:[PDB_Exit+2],AX
PUSH ES
MOV ES,[TRAN_TPA]
MOV AH,DEALLOC
INT 21h ; Now running in "free" space
POP ES
MOV AH,Exit
MOV AL,BYTE PTR RetCode
INT 21h
; ****************************************************************
; *
; * ROUTINE: PARSE_CHECK_EOL
; *
; * FUNCTION: Calls parser to see if end of line occurred.
; * If not end of line, set up to print parse
; * error message. ASSUMES NO MORE PARAMETERS ARE
; * EXPECTED!
; *
; * INPUT: DS:SI last output from parser
; * ES:DI points to parse block
; * CX last output from parser
; *
; * OUTPUT: AX parser return code
; *
; * if end of line found
; * zero flag set
; * else
; * MSG_DISPLAY_CLASS set to parse error
; *
; ****************************************************************
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN000;
parse_check_eol Proc near ;AN000;
xor dx,dx ;AN000;
mov [parse_last],si ;AN018; save start of parameter
invoke cmd_parse ;AN000; call parser
cmp al,end_of_line ;AN000; Are we at end of line?
jz parse_good_eol ;AN000; yes - no problem
cmp ax,result_no_error ;AN018; was any error found?
jnz ok_to_setup_pmsg ;AN018; yes - continue
inc ax ;AN018; set AX to 1 and turn off zero flag
ok_to_setup_pmsg:
call setup_parse_error_msg ;AN018; go set up error message
parse_good_eol:
ret ;AN000;
parse_check_eol endp ;AN000;
; ****************************************************************
; *
; * ROUTINE: PARSE_WITH_MSG
; *
; * FUNCTION: Calls parser. If an error occurred, the error
; * message is set up.
; *
; * INPUT: DS:SI last output from parser
; * ES:DI points to parse block
; * CX last output from parser
; *
; * OUTPUT: AX parser return code
; *
; * if no error
; * outputs from parser
; * else
; * MSG_DISPLAY_CLASS set to parse error
; * error message set up for STD_PRINTF
; *
; ****************************************************************
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN018;
parse_with_msg Proc near ;AN018;
mov [parse_last],si ;AN018; save start of parameter
invoke cmd_parse ;AN018; call parser
cmp al,end_of_line ;AN018; Are we at end of line?
jz parse_msg_good ;AN018; yes - no problem
cmp ax,result_no_error ;AN018; did an error occur
jz parse_msg_good ;AN018; yes - no problem
call setup_parse_error_msg ;AN018; go set up error message
parse_msg_good:
ret ;AN018;
parse_with_msg endp ;AN018;
; ****************************************************************
; *
; * ROUTINE: SETUP_PARSE_ERROR_MSG
; *
; * FUNCTION: Calls parser. If an error occurred, the error
; * message is set up.
; *
; * INPUT: AX Parse error number
; * SI Set to past last parameter
; * Parse_last Set to start of last parameter
; *
; * OUTPUT: MSG_DISPLAY_CLASS set to parse error
; * error message set up for STD_PRINTF
; *
; ****************************************************************
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN018;
SETUP_PARSE_ERROR_MSG Proc near ;AN018;
mov msg_disp_class,parse_msg_class ;AC018; Set up parse message class
mov dx,offset TranGroup:Extend_Buf_ptr ;AC018; get extended message pointer
mov byte ptr [si],end_of_line_out ;AC018; terminate the parameter string
mov Extend_Buf_ptr,ax ;AC018; get message number in control block
cmp ax,lessargs_ptr ;AC018; if required parameter missing
jz Setup_parse_msg_ret ;AN018; no subst
mov si,[parse_last] ;AC018; get start of parameter
mov string_ptr_2,si ;AC018; get address of failed string
mov Extend_buf_sub,one_subst ;AC018; put number of subst in control block
setup_parse_msg_ret:
inc si ;AN018; make sure zero flag not set
ret ;AC018;
SETUP_PARSE_ERROR_MSG Endp ;AN018;
trancode ends
end