path.asm
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:11k
源码类别:
操作系统开发
开发平台:
Visual C++
- Page ,132
- title Path Searching Routines
- ; PATH.ASM - Code to search the environment for a particular data string,
- ; and to search the path for a particular file. Adapted from the original
- ; COMMAND.COM version.
- ;
- ; Routines supported:
- ; Find_in_Environment - locate the start of a given string
- ; in the environment
- ; Path_Crunch - concantenates a file name with a directory path from
- ; the PATH environment variable
- ; Search - Finds executable or other files, given a base name
- ;
- include dossym.inc
- include curdir.inc
- include find.inc
- include pdb.inc
- include syscall.inc
- DATA segment para public
- Path_str db "PATH="
- Path_str_size equ $ - offset Path_Str
- Comspec_str db "COMSPEC="
- Comspec_str_size equ $ - offset Comspec_str
- DATA ends
- CODE segment para public
- assume cs:CODE,ds:DATA
- IFDEF DBCS
- extrn IsDBCSLeadByte:near
- ENDIF
- ;----------------------------------------------------------------------------
- ; Path_Crunch - takes a pointer into a environment PATH string and a file
- ; name, and sticks them together, for subsequent searching.
- ;
- ; ENTRY:
- ; BH -- additional terminator character (i.e., ';')
- ; DS:SI -- pointer into pathstring to be dissected
- ; ES:DI -- buffer to store target name
- ; DX -- pointer to filename
- ; EXIT:
- ; SI -- moves along pathstring from call to call
- ; ES:DI -- filled in with concatenated name
- ; Carry set if end of path string has been reached.
- ;
- ;---------------
- Path_Crunch PROC NEAR
- public Path_Crunch
- ;---------------
- assume ds:nothing
- assume es:DATA
- IFDEF DBCS
- xor cl,cl ; clear flag for later use 3/3/KK
- ENDIF
- path_cr_copy:
- lodsb ; get a pathname byte
- or al,al ; check for terminator(s)
- jz path_seg ; null terminates segment & pathstring
- cmp AL, BH
- jz path_seg ; BH terminates a pathstring segment
- IFDEF DBCS
- invoke IsDBCSLeadByte ;
- jz NotKanj2 ;
- stosb ;
- movsb ;
- MOV CL,1 ; CL=1 means latest stored char is DBCS
- jmp path_cr_copy ;
- NotKanj2: ;
- xor cl,cl ; CL=0 means latest stored char is SBCS
- ENDIF
- stosb ; save byte in concat buffer
- jmp path_cr_copy ; loop until we see a terminator
- path_seg:
- push si ; save resting place in env. seg.
- mov BL, AL ; remember if we saw null or not...
- path_cr_look: ; form complete pathname
- mov al, '' ; add pathname separator for suffix
- IFDEF DBCS
- or cl,cl ;
- jnz path_cr_store ; this is a trailing byte of ECS code 3/3/KK
- ENDIF
- cmp al,es:byte ptr [di-1]
- jz path_cr_l1
- path_cr_store:
- stosb
- path_cr_l1:
- mov SI, DX
- path_cr_l2:
- lods byte ptr es:[si] ; tack the stripped filename onto
- stosb ; the end of the path, up to and
- or AL, AL ; including the terminating null
- jnz path_cr_l2
- path_cr_leave:
- or BL, BL ; did we finish off the pathstring?
- clc
- jnz path_cr_exit ; null in BL means all gone...
- cmc
- path_cr_exit:
- pop si ; retrieve
- ret
- assume es:nothing
- ;---------------
- Path_Crunch endp
- ;----------------------------------------------------------------------------
- ;----------------------------------------------------------------------------
- ; SEARCH, when given a pathname, attempts to find a file with
- ; one of the following extensions: .com, .exe (highest to
- ; lowest priority). Where conflicts arise, the extension with
- ; the highest priority is favored.
- ; ENTRY:
- ; DX -- pointer to null-terminated pathname
- ; BX -- dma buffer for findfirst/next
- ; AL -- 0 if we should look for .COM and .EXE extensions
- ; 1 if extensions is pre-specified
- ; EXIT:
- ; AX -- 8) file found with .com extension, or file with
- ; pre-specified extension found
- ; 4) file found with .exe extension
- ; 0) no such file to be found
- ; DX -- points to resolved path name
- ; DS -- DATA
- ; NOTES:
- ; 1) Requires caller to have allocated executed a setdma.
- ;
- ;---------------
- ; CONSTANTS:
- ;---------------
- search_attr equ attr_read_only+attr_hidden
- search_file_not_found equ 0
- search_com equ 8
- search_exe equ 4
- fname_len equ 8
- fname_max_len equ 23
- dot equ '.'
- wildchar equ '?'
- search_best db (?)
- ;---------------
- Search PROC NEAR
- public Search
- ;---------------
- push si ;
- push ax ; save extension flag
- mov DI, DX ; working copy of pathname
- mov CX, search_attr ; filetypes to search for
- mov ah, Find_First ; request first match, if any
- int 21h
- pop ax
- jc search_no_file
- or al,al ; looking for specific ext?
- jz search_no_ext ; no, jump
- mov search_best,search_com ; report we found best match
- jmp short search_file_found ; yes, found it
- search_no_ext:
- mov search_best, search_file_not_found
- search_loop:
- call search_ftype ; determine if .com, &c...
- cmp AL, search_best ; better than what we've found so far?
- jle search_next ; no, look for another
- mov search_best, AL ; found something... save its code
- cmp AL, search_com ; have we found the best of all?
- je search_done
- search_next: ; keep on looking
- mov CX, search_attr
- mov ah, Find_Next ; next match
- int 21h
- jnc search_loop
- search_done: ; it's all over with...
- cmp search_best, search_file_not_found
- je search_no_file
- cmp search_best, search_com
- mov si, offset comext
- je search_move_ext
- mov si, offset exeext
- search_move_ext:
- mov di, dx
- mov al, '.'
- mov cx, DIRSTRLEN
- rep scasb
- dec di
- movsw
- movsw
- search_file_found:
- mov al, search_best
- jmp short search_exit
- search_no_file: ; couldn't find a match
- mov AX, search_file_not_found
- search_exit:
- pop si
- ret
- Search endp
- ;----------------------------------------------------------------------------
- ;----------------------------------------------------------------------------
- ; SEARCH_FTYPE determines the type of a file by examining its extension.
- ; ENTRY:
- ; BX -- dma buffer containing filename
- ; EXIT:
- ; AL -- file code, as given in search header
- ;---------------
- comext db ".COM",0
- exeext db ".EXE",0
- Search_Ftype PROC NEAR
- public Search_Ftype
- push DI
- mov AL, search_file_not_found ; find the end of the filename
- mov DI, BX
- add si,Find_Buf_Pname
- mov CX, fname_max_len
- cld
- repnz scasb ; search for the terminating null
- jnz ftype_exit ; weird... no null byte at end
- ;
- ; Scan backwards to find the start of the extension
- ;
- dec di ; point back to null
- mov cx, 5 ; . + E + X + T + null
- std ; scan back
- mov al, '.'
- repnz scasb
- jnz ftype_exit ; must not be any extension
- inc di ; point to start of extension
- cld
- ;
- ; Compare .COM
- ;
- mov si,offset comext
- mov ax,di
- cmpsw
- jnz ftype_exe
- cmpsw
- jnz ftype_exe
- mov AL, search_com ; success!
- jmp short ftype_exit
- ;
- ; Compare .EXE
- ;
- ftype_exe: ; still looking... now for '.exe'
- mov di,ax
- mov si,offset exeext
- cmpsw
- jnz ftype_fail
- cmpsw
- jnz ftype_fail
- mov AL, search_exe ; success!
- jmp short ftype_exit
- ftype_fail: ; file doesn't match what we need
- mov al,search_file_not_found
- ftype_exit:
- pop DI
- ret
- Search_Ftype endp
- ;----------------------------------------------------------------------------
- ;
- ; Find_Comspec_In_Environment - find the beginning of the COMSPEC string
- ; Entry : DS = DATA
- ; ES = PSP
- ; Exit : ES:DI => start of Comspec path
- ;
- FIND_COMSPEC_IN_environment PROC NEAR
- public Find_Comspec_In_Environment
- lea si,Comspec_str
- mov cx,Comspec_str_size ; cx = length of name
- jmp short Find_in_Environment
- Find_Comspec_in_Environment endp
- ;----------------------------------------------------------------------------
- ;
- ; Find_Path_In_Environment - find the beginning of the PATH string
- ; Entry : DS = DATA
- ; ES = PSP
- ; Exit : ES:DI => start of Path directory list
- ;
- FIND_PATH_IN_environment PROC NEAR
- public Find_Path_In_Environment
- lea si,Path_str
- mov cx,Path_str_size ; cx = length of name
- ; fall through to following
- Find_Path_in_Environment endp
- ; Find_In_Environment - locate a given string in the environment
- ;
- ; Input : SI = name to find in environment
- ; CX = length of name
- ; DS = DATA
- ; ES = PSP segment
- ;
- ; Output: ES:DI points to the arguments in the environment
- ; carry is set if name not found
- ;
- Find_in_Environment PROC NEAR
- public Find_In_Environment
- cld
- xor di,di
- mov ax,es:[di].PDB_Environ
- or ax,ax ; is there an environment?
- jz find_nf_exit ; no, quit now
- mov es,ax
- assume es:nothing
- find1:
- push si
- push cx ; save starting values
- find11:
- ifdef dbcs
- lodsb
- call IsDBCSLeadByte
- jz notkanj3
- dec si
- lodsw
- inc di
- inc di
- cmp ax,es:[di-2]
- jnz find12
- dec cx
- loop find11
- jmp short find12
- notkanj3:
- inc di
- cmp al,es:[di-1]
- jnz find12
- loop find11
- else ;dbcs
- repe cmpsb
- endif ;dbcs
- find12:
- pop dx
- pop si ; clear stack
- jz find_exit
- dec di
- xor al,al ; scan for a nul
- mov cx,100h ; arbitrary size
- repnz scasb
- cmp byte ptr es:[di],0 ; check for trailing null
- mov cx,dx ; original count back in CX
- jnz find1
- find_nf_exit:
- stc ; indicate not found
- find_exit:
- ret
- Find_in_environment endp
- CODE ends
- end