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.
 
 
 
 
 
 

596 lines
17 KiB

;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1991
; * All Rights Reserved.
; */
************************************************************
************************************************************
** **
** THIS FILE IS OBSOLETE, NO LONGER USED, DEFUNCT, **
** AND, IN FACT, DOESN'T EVEN EXIST. YOU ARE NOT **
** HERE. YOU MAY NOT BE ANYWHERE AT ALL. THIS **
** WHOLE THING COULDN'T POSSIBLY BE HAPPENING. **
** **
** See DIR.ASM for a reality check. **
** **
************************************************************
************************************************************
page 80,132
; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14
; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14
TITLE PART4 COMMAND Transient routines.
; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER
INCLUDE comsw.asm
.xlist
.xcref
INCLUDE DOSSYM.INC
INCLUDE comseg.asm
INCLUDE comequ.asm ;AC000;
include ioctl.inc ;AN000;
.list
.cref
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
EXTRN BadCD_ptr:word
EXTRN bits:word
EXTRN Bytmes_ptr:word
EXTRN comsw:word
EXTRN dir_w_syn:word ;AC000;
EXTRN dirdat_mo_day:word ;AC000;
EXTRN dirdat_yr:word ;AC000;
EXTRN dirdattim_ptr:word
EXTRN dirhead_ptr:word
EXTRN dirtim_hr_min:word ;AC000;
EXTRN Dirmes_ptr:word
EXTRN disp_file_size_ptr:word
EXTRN Dmes_ptr:word
EXTRN Extend_buf_ptr:word ;AN000;
EXTRN msg_disp_class:byte ;AN000;
EXTRN parse_dir:byte ;AC000;
EXTRN slash_p_syn:word ;AC000;
EXTRN string_buf_ptr:word
EXTRN tab_ptr:word ;AC000;
TRANDATA ENDS
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
EXTRN bytes_free:word
EXTRN charbuf:byte
EXTRN COM:byte
EXTRN Destisdir:byte
EXTRN Desttail:word
EXTRN dir_num:word
EXTRN Dirbuf:byte
EXTRN dirflag:byte ;AN015;
EXTRN display_ioctl:word ;AC000;
EXTRN display_mode:byte ;AC000;
EXTRN filecnt:word
EXTRN file_size_high:word
EXTRN file_size_low:word
EXTRN fullscr:word
EXTRN ID:byte
EXTRN lincnt:byte ;AC000;
EXTRN linlen:byte
EXTRN linperpag:word ;AC000;
EXTRN msg_numb:word ;AN022;
EXTRN parse1_addr:dword ;AC000;
EXTRN parse1_syn:word ;AC000;
EXTRN parse1_type:byte ;AC000;
EXTRN pathcnt:word ;AN000;
EXTRN pathpos:word ;AN000;
EXTRN srcbuf:byte ;AC000;
EXTRN string_ptr_2: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 std_printf:near
PUBLIC catalog
break Catalog - Directory command
assume ds:trangroup,es:trangroup
;
; The DIR command displays the contents of a directory.
;
; ****************************************************************
; *
; * ROUTINE: CATALOG - display file(s) in directory
; *
; * FUNCTION: PARSE command line for drive, file, or path name.
; * DIR allows two switches, /P (pause) and /W (wide).
; * If an error occurs issue and error message and
; * transfer control to CERROR.
; *
; * INPUT: command line at offset 81H
; *
; * OUTPUT: none
; *
; ****************************************************************
CATALOG:
;
; Set up DTA for dir search firsts
;
mov dx,offset trangroup:Dirbuf ;AC000; Set Disk transfer address
mov ah,Set_DMA ;AC000;
int int_command ;AC000;
;
; Set up defaults for switches and parse the command line.
;
mov msg_numb,0 ;AN022; initialize message flag
mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf
mov [pathpos],di ;AN000; this is start of path
mov [pathcnt],1 ;AN000; initialize length to 1 char
mov al,star ;AN000; initialize srcbuf to *,0d
stosb ;AN000;
mov al,end_of_line_in ;AN000;
stosb ;AN000;
mov si,81H ;AN000; Get command line
mov di,offset trangroup:parse_dir ;AN000; Get adderss of PARSE_DIR
xor cx,cx ;AC000; clear counter for positionals
mov ComSw,cx ;AC000; initialize flags
mov bits,cx ;AC000; initialize switches
mov linperpag,linesperpage ;AC000; Set default for lines per page
mov linlen,normperlin ;AC000; Set number of entries per line
mov lincnt,normperlin ;AC000;
dirscan:
xor dx,dx ;AN000;
invoke parse_with_msg ;AC018; call parser
cmp ax,end_of_line ;AN000; are we at end of line?
jne dirscan_cont ;AN000; No - continue parsing
jmp scandone ;AN000; yes - go process
dirscan_cont:
cmp ax,result_no_error ;AN000; did we have an error?
jz dirscan_cont2 ;AN000; No - continue parsing
jmp badparm ;AN000; yes - exit
dirscan_cont2:
cmp parse1_syn,offset trangroup:dir_w_syn ;AN000; was /W entered?
je set_dir_width ;AN000; yes - go set wide lines
cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered?
je set_dir_pause ;AN000; yes - go set pause at end of screen
;
; Must be filespec since no other matches occurred. move filename to srcbuf
;
push si ;AC000; save position in line
lds si,parse1_addr ;AC000; get address of filespec
push si ;AN000; save address
invoke move_to_srcbuf ;AC000; move to srcbuf
pop dx ;AC000; get address in DX
;
; The user may have specified a device. Search for the path and see if the
; attributes indicate a device.
;
mov ah,Find_First ;AC000; find the file
int int_command ;AC000;
jnc Dir_check_device ;AN022; if no error - check device
invoke get_ext_error_number ;AN022; get the extended error
cmp ax,error_no_more_files ;AN022; was error no file found
jz Dir_fspec_end ;AC022; yes -> obviously not a device
cmp ax,error_path_not_found ;AN022; was error no file found
jz Dir_fspec_end ;AC022; yes -> obviously not a device
jmp dir_err_setup ;AN022; otherwise - go issue error message
dir_check_device: ;AN022;
test byte ptr (DirBuf+find_buf_attr),attr_device ;AC000;
jz Dir_fspec_end ;AC000; no, go do normal operation
mov ComSw,-2 ;AC000; signal device
dir_fspec_end:
pop si ;AC000; restore position in line
jmp short dirscan ;AC000; keep parsing
set_dir_width:
test byte ptr[bits],SwitchW ;AN018; /W already set?
jz ok_set_width ;AN018; no - okay to set width
mov ax,moreargs_ptr ;AN018; set up too many arguments
invoke setup_parse_error_msg ;AN018; set up an error message
jmp badparm ;AN018; exit
ok_set_width:
or bits,switchw ;AC000; indicate /w was selected
mov linlen,wideperlin ;AC000; Set number of entries per line
mov lincnt,wideperlin ;AC000;
jmp short dirscan ;AC000; keep parsing
set_dir_pause:
test byte ptr[bits],SwitchP ;AN018; /p already set?
jz ok_set_pause ;AN018; no - okay to set width
mov ax,moreargs_ptr ;AN018; set up too many arguments
invoke setup_parse_error_msg ;AN018; set up an error message
jmp badparm ;AN018; exit
ok_set_pause:
or bits,switchp ;AC000; indicate /p was selected
push cx ;AN000; save necessary registers
push si ;AN000;
mov ax,(IOCTL SHL 8) + generic_ioctl_handle ;AN000; get lines per page on display
mov bx,stdout ;AN000; lines for stdout
mov ch,ioc_sc ;AN000; type is display
mov cl,get_generic ;AN000; get information
mov dx,offset trangroup:display_ioctl ;AN000;
int int_command ;AN000;
lines_set:
dec linperpag ;AN000; lines per actual page should
dec linperpag ;AN000; two less than the max
mov ax,linperpag ;AN000; get number of lines into
mov [fullscr],ax ;AC000; screen line counter
pop si ;AN000; restore registers
pop cx ;AN000;
jmp dirscan ;AC000; keep parsing
;
; The syntax is incorrect. Report only message we can.
;
BadParm:
jmp cerror ;AC000; invalid switches get displayed
ScanDone:
;
; Find and display the volume ID on the drive.
;
invoke okvolarg ;AC000;
;
; OkVolArg also disables APPEND, which will be re-enabled
; in the HeadFix routine, after we're done.
;
mov [filecnt],0 ;AC000; Keep track of how many files found
cmp comsw,0 ;AC000; did an error occur?
jnz doheader ;AC000; yes - don't bother to fix path
mov dirflag,-1 ;AN015; set pathcrunch called from DIR
invoke pathcrunch ;AC000; set up FCB for dir
mov dirflag,0 ;AN015; reset dirflag
jc DirCheckPath ;AC015; no CHDIRs worked.
jz doheader ;AC015; chdirs worked - path\*.*
mov si,[desttail] ;AN015; get filename back
jmp short DoRealParse ;AN015; go parse it
DirCheckPath:
mov ax,[msg_numb] ;AN022; get message number
cmp ax,0 ;AN022; Is there a message?
jnz dir_err_setup ;AN022; yes - there's an error
cmp [destisdir],0 ;AC000; Were pathchars found?
jz doparse ;AC000; no - no problem
inc comsw ;AC000; indicate error
jmp short doheader ;AC000; go print header
DirNF:
mov ax,error_file_not_found ;AN022; get message number in control block
dir_err_setup:
mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
mov extend_buf_ptr,ax ;AN022;
DirError:
jmp Cerror
;
; We have changed to something. We also have a file. Parse it into a
; reasonable form, leaving drive alone, leaving extention alone and leaving
; filename alone. We need to special case ... If we are at the root, the
; parse will fail and it will give us a file not found instead of file not
; found.
;
DoParse:
mov si,offset trangroup:srcbuf ;AN000; Get address of source
cmp byte ptr [si+1],colon_char ;AN000; Is there a drive?
jnz dir_no_drive ;AN000; no - keep going
lodsw ;AN000; bypass drive
dir_no_drive:
cmp [si],".."
jnz DoRealParse
cmp byte ptr [si+2],0
jnz DoRealParse
inc ComSw
jmp short DoHeader
DoRealParse:
mov di,FCB ; where to put the file name
mov ax,(Parse_File_Descriptor SHL 8) OR 0EH
int int_command
;
; Check to see if APPEND installed. If it is installed, set all flags
; off. This will be reset in the HEADFIX routine
;
DoHeader:
; ORIGINAL APPEND CHECK CODE LOCATION ******************************
;
; Display the header
;
DoHeaderCont:
mov al,blank ;AN051; Print out a blank
invoke print_char ;AN051; before DIR header
invoke build_dir_string ; get current dir string
mov dx,offset trangroup:Dirhead_ptr
invoke printf_crlf ; bang!
;
; If there were chars left after parse or device, then invalid file name
;
cmp ComSw,0
jz DoSearch ; nothing left; good parse
jl DirNFFix ; not .. => error file not found
invoke RestUDir
mov dx,offset TranGroup:BadCD_ptr
jmp Cerror ; was .. => error directory not found
DirNFFix:
invoke RestUDir
jmp DirNF
;
; We are assured that everything is correct. Let's go and search. Use
; attributes that will include finding directories. perform the first search
; and reset our directory afterward.
;
DoSearch:
mov byte ptr DS:[FCB-7],0FFH
mov byte ptr DS:[FCB-1],010H
;
; Caution! Since we are using an extended FCB, we will *also* be returning
; the directory information as an extended FCB. We must bias all fetches into
; DIRBUF by 8 (Extended FCB part + drive)
;
mov ah,Dir_Search_First
mov dx,FCB-7
int int_command
push ax ;AN022; save return state
inc al ;AN022; did an error occur?
pop ax ;AN022; get return state back
jnz found_first_file ;AN022; no error - start dir
invoke set_ext_error_msg ;AN022; yes - set up error message
push dx ;AN022; save message
invoke restudir ;AN022; restore user's dir
pop dx ;AN022; restore message
cmp word ptr Extend_Buf_Ptr,Error_No_More_Files ;AN022; convert no more files to
jnz DirCerrorJ ;AN022; file not found
mov Extend_Buf_Ptr,Error_File_Not_Found ;AN022;
DirCerrorJ: ;AN022;
jmp Cerror ;AN022; exit
;
; Restore the user's directory. We preserve, though, the return from the
; previous system call for later checking.
;
found_first_file:
push ax
invoke restudir
pop ax
;
; Main scanning loop. Entry has AL = Search first/next error code. Test for
; no more.
;
DIRSTART:
inc al ; FF = file not found
jnz Display
jmp DirDone ; Either an error or we are finished
;
; Note that we've seen a file and display the found file.
;
Display:
inc [filecnt] ; Keep track of how many we find
mov si,offset trangroup:dirbuf+8 ; SI -> information returned by sys call
call shoname
;
; If we are displaying in wide mode, do not output the file info
;
test byte ptr[bits],SwitchW ; W switch set?
jz DirTest
jmp nexent ; If so, no size, date, or time
;
; Test for directory.
;
DirTest:
test [dirbuf+8].dir_attr,attr_directory
jz fileent
;
; We have a directory. Display the <DIR> field in place of the file size
;
mov dx,offset trangroup:Dmes_ptr
call std_printf
jmp short nofsiz
;
; We have a file. Display the file size
;
fileent:
mov dx,[DirBuf+8].dir_size_l
mov file_size_low,dx
mov dx,[DirBuf+8].dir_size_h
mov file_size_high,dx
mov dx,offset trangroup:disp_file_size_ptr
call std_printf
;
; Display time and date of last modification
;
nofsiz:
mov ax,[DirBuf+8].dir_date ; Get date
;
; If the date is 0, then we have found a 1.x level diskette. We skip the
; date/time fields as 1.x did not have them.
;
or ax,ax
jz nexent ; Skip if no date
mov bx,ax
and ax,1FH ; get day
mov dl,al
mov ax,bx
mov cl,5
shr ax,cl ; Align month
and al,0FH ; Get month
mov dh,al
mov cl,bh
shr cl,1 ; Align year
xor ch,ch
add cx,80 ; Relative 1980
cmp cl,100
jb millenium
sub cl,100
millenium:
xchg dh,dl ;AN000; switch month & day
mov DirDat_yr,cx ;AC000; put year into message control block
mov DirDat_mo_day,dx ;AC000; put month and day into message control block
mov cx,[DirBuf+8].dir_time ; Get time
jcxz prbuf ; Time field present?
shr cx,1
shr cx,1
shr cx,1
shr cl,1
shr cl,1 ; Hours in CH, minutes in CL
xchg ch,cl ;AN000; switch hours & minutes
mov DirTim_hr_min,cx ;AC000; put hours and minutes into message subst block
prbuf:
mov dx,offset trangroup:DirDatTim_ptr
call std_printf
invoke crlf2 ;AC066;end the line
dec byte ptr [fullscr] ;AC066;count the line
jnz endif04 ;AN066;IF the last on the screen THEN
call check_for_P ;AN066; pause if /P requested
endif04: ;AN066;
jmp scroll ; If not, just continue
;AD061; mov DirDat_yr,0 ;AC000; reset year, month and day
;AD061; mov DirDat_mo_day,0 ;AC000; in control block
;AD061; mov DirTim_hr_min,0 ;AC000; reset hour & minute in control block
;
; We are done displaying an entry. The code between "noexent:" and "scroll:"
; is only for /W case.
;
nexent:
mov bl,[lincnt] ;AN066;save for check for first entry on line
dec [lincnt] ;count this entry on the line
jnz else01 ;AX066;IF last entry on line THEN
mov al,[linlen]
mov [lincnt],al
invoke crlf2
cmp [fullscr],0 ;AC066;IF have filled the screen THEN
jnz endif02 ;AN066;
call check_for_P ;AN066; reinitialize fullscr,
endif02: ;AN066; IF P requested THEN pause
jmp short endif01 ;AN066;
else01: ;AN066;ELSE since screen not full
cmp bl,[linlen] ;AN066; IF starting new line THEN
jne endif03 ; count the line
dec byte ptr [fullscr] ;AN066; ENDIF
endif03: ;AC066;We are outputting on the same line, between fields, we tab.
mov dx,offset trangroup:tab_ptr ;Output a tab
call std_printf
endif01: ;AX066;
;
; All we need to do now is to get the next directory entry.
;
scroll:
mov ah,Dir_Search_Next
mov dx,FCB-7 ; DX -> Unopened FCB
int int_command ; Search for a file to match FCB
jmp DirStart
;
; If no files have been found, display a not-found message
;
DirDone:
invoke get_ext_error_number ;AN022; get the extended error number
cmp ax,error_no_more_files ;AN022; was error file not found?
jnz dir_err_setup_jmp ;AN022; no - setup error message
test [filecnt],-1
jnz Trailer
mov ax,error_file_not_found ;AN022;
dir_err_setup_jmp: ;AN022;
jmp dir_err_setup ;AN022; go setup error msg & print it
;
; If we have printed the maximum number of files per line, terminate it with
; CRLF.
;
Trailer:
mov al,[linlen]
cmp al,[lincnt] ; Will be equal if just had CR/LF
jz mmessage
invoke crlf2
cmp [fullscr],0 ;AN066;IF on last line of screen THEN
jnz endif06 ;AN066; pause before going on
call check_for_P ;AN066; to number and freespace
endif06: ;AN066; displays
mmessage:
mov dx,offset trangroup:Dirmes_ptr
mov si,[filecnt]
mov dir_num,si
call std_printf
mov ah,Get_Drive_Freespace
mov dl,byte ptr DS:[FCB]
int int_command
cmp ax,-1
retz
mul cx ; AX is bytes per cluster
mul bx
mov bytes_free,ax ;AC000;
mov bytes_free+2,dx ;AC000;
MOV DX,OFFSET TRANGROUP:BYTMES_ptr
jmp std_printf
shoname:
mov di,offset trangroup:charbuf
mov cx,8
rep movsb
mov al,' '
stosb
mov cx,3
rep movsb
xor ax,ax
stosb
push dx
mov dx,offset trangroup:charbuf
mov string_ptr_2,dx
mov dx,offset trangroup:string_buf_ptr
call std_printf
pop DX
return
check_for_P PROC NEAR ;AN066;
test byte ptr[bits],SwitchP ;P switch present?
jz endif05 ;AN066;
mov ax,linperpag ;AN000; transfer lines per page
mov [fullscr],ax ;AC000; to fullscr
invoke Pause
endif05:
ret ;AN066;
check_for_P ENDP ;AN066;
trancode ends
end