path.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:11k
源码类别:

操作系统开发

开发平台:

Visual C++

  1.         Page    ,132
  2.         title   Path Searching Routines
  3. ; PATH.ASM - Code to search the environment for a particular data string,
  4. ; and to search the path for a particular file.  Adapted from the original
  5. ; COMMAND.COM version.
  6. ;
  7. ; Routines supported:
  8. ;       Find_in_Environment - locate the start of a given string
  9. ;                               in the environment
  10. ;       Path_Crunch - concantenates a file name with a directory path from
  11. ;                       the PATH environment variable
  12. ;       Search - Finds executable or other files, given a base name
  13. ;
  14.         include dossym.inc
  15.         include curdir.inc
  16.         include find.inc
  17.         include pdb.inc
  18.         include syscall.inc
  19.         DATA segment para public
  20. Path_str        db      "PATH="
  21. Path_str_size   equ     $ - offset Path_Str
  22. Comspec_str     db      "COMSPEC="
  23. Comspec_str_size equ    $ - offset Comspec_str
  24.         DATA ends
  25.         CODE segment para public
  26.         assume cs:CODE,ds:DATA
  27. IFDEF DBCS
  28.         extrn   IsDBCSLeadByte:near
  29. ENDIF
  30. ;----------------------------------------------------------------------------
  31. ; Path_Crunch - takes a pointer into a environment PATH string and a file
  32. ; name, and sticks them together, for subsequent searching.
  33. ;
  34. ; ENTRY:
  35. ;   BH -- additional terminator character (i.e., ';')
  36. ;   DS:SI -- pointer into pathstring to be dissected
  37. ;   ES:DI               --      buffer to store target name
  38. ;   DX -- pointer to filename
  39. ; EXIT:
  40. ;   SI -- moves along pathstring from call to call
  41. ;   ES:DI               --      filled in with concatenated name
  42. ;   Carry set if end of path string has been reached.
  43. ;
  44. ;---------------
  45. Path_Crunch PROC NEAR
  46.         public  Path_Crunch
  47. ;---------------
  48.         assume  ds:nothing
  49.         assume  es:DATA
  50. IFDEF DBCS
  51. xor cl,cl ; clear flag for later use 3/3/KK
  52. ENDIF
  53. path_cr_copy:
  54. lodsb ; get a pathname byte
  55. or al,al ; check for terminator(s)
  56. jz path_seg ; null terminates segment & pathstring
  57. cmp AL, BH
  58. jz path_seg ; BH terminates a pathstring segment
  59. IFDEF DBCS
  60. invoke IsDBCSLeadByte ;
  61. jz NotKanj2 ;
  62. stosb ;
  63. movsb ;
  64. MOV CL,1 ; CL=1 means latest stored char is DBCS
  65. jmp path_cr_copy ;
  66. NotKanj2: ;
  67. xor cl,cl ; CL=0 means latest stored char is SBCS
  68. ENDIF
  69. stosb ; save byte in concat buffer
  70. jmp path_cr_copy ; loop until we see a terminator
  71. path_seg:
  72.         push    si                              ; save resting place in env. seg.
  73. mov BL, AL ; remember if we saw null or not...
  74. path_cr_look: ; form complete pathname
  75. mov al, ''       ; add pathname separator for suffix
  76. IFDEF DBCS
  77. or cl,cl ;
  78. jnz path_cr_store ; this is a trailing byte of ECS code 3/3/KK
  79. ENDIF
  80. cmp al,es:byte ptr [di-1]
  81. jz path_cr_l1
  82. path_cr_store:
  83. stosb
  84. path_cr_l1:
  85. mov SI, DX
  86. path_cr_l2:
  87. lods byte ptr es:[si]        ; tack the stripped filename onto
  88. stosb ; the end of the path, up to and
  89. or AL, AL ; including the terminating null
  90. jnz path_cr_l2
  91. path_cr_leave:
  92. or BL, BL ; did we finish off the pathstring?
  93. clc
  94.         jnz path_cr_exit ; null in BL means all gone...
  95. cmc
  96. path_cr_exit:
  97.         pop     si                              ; retrieve
  98. ret
  99.         assume  es:nothing
  100. ;---------------
  101. Path_Crunch endp
  102. ;----------------------------------------------------------------------------
  103. ;----------------------------------------------------------------------------
  104. ;   SEARCH, when given a pathname, attempts to find a file with
  105. ; one of the following extensions:  .com, .exe (highest to
  106. ; lowest priority).  Where conflicts arise, the extension with
  107. ; the highest priority is favored.
  108. ; ENTRY:
  109. ;   DX -- pointer to null-terminated pathname
  110. ;   BX   -- dma buffer for findfirst/next
  111. ;   AL          --      0 if we should look for .COM and .EXE extensions
  112. ;                       1 if extensions is pre-specified
  113. ; EXIT:
  114. ;   AX -- 8)  file found with .com extension, or file with
  115. ;                           pre-specified extension found
  116. ; 4)  file found with .exe extension
  117. ; 0)  no such file to be found
  118. ;   DX          --      points to resolved path name 
  119. ;   DS          --      DATA
  120. ; NOTES:
  121. ;   1) Requires caller to have allocated executed a setdma.
  122. ;       
  123. ;---------------
  124. ; CONSTANTS:
  125. ;---------------
  126. search_attr                 equ         attr_read_only+attr_hidden
  127. search_file_not_found     equ  0
  128. search_com     equ  8
  129. search_exe     equ  4
  130. fname_len     equ  8
  131. fname_max_len     equ  23
  132. dot     equ  '.'
  133. wildchar     equ  '?'
  134. search_best                 db          (?)
  135. ;---------------
  136. Search PROC NEAR
  137.         public Search
  138. ;---------------
  139.         push    si                              ; 
  140.         push    ax                              ; save extension flag
  141. mov DI, DX ; working copy of pathname
  142. mov CX, search_attr  ; filetypes to search for
  143.         mov     ah, Find_First ; request first match, if any
  144.         int     21h
  145.         pop     ax                              
  146. jc search_no_file
  147.         
  148.         or      al,al                           ; looking for specific ext?
  149.         jz      search_no_ext                   ; no, jump
  150.         mov     search_best,search_com          ; report we found best match
  151.         jmp     short search_file_found         ; yes, found it
  152. search_no_ext:
  153.         mov     search_best, search_file_not_found
  154. search_loop:
  155. call search_ftype ; determine if .com, &c...
  156. cmp AL, search_best  ; better than what we've found so far?
  157. jle search_next ; no, look for another
  158. mov search_best, AL  ; found something... save its code
  159. cmp AL, search_com ; have we found the best of all?
  160. je search_done
  161. search_next: ; keep on looking
  162. mov CX, search_attr
  163.         mov     ah, Find_Next                   ; next match
  164.         int     21h
  165. jnc search_loop
  166. search_done: ; it's all over with...
  167.         cmp     search_best, search_file_not_found
  168.         je      search_no_file
  169.         cmp     search_best, search_com
  170.         mov     si, offset comext
  171.         je      search_move_ext
  172.         mov     si, offset exeext
  173. search_move_ext:
  174.         mov     di, dx
  175.         mov     al, '.'
  176.         mov     cx, DIRSTRLEN
  177.         rep     scasb
  178.         dec     di
  179.         movsw   
  180.         movsw   
  181. search_file_found:
  182.         mov     al, search_best
  183. jmp short search_exit
  184. search_no_file:  ; couldn't find a match
  185. mov AX, search_file_not_found
  186. search_exit:
  187.         pop     si
  188. ret
  189. Search endp
  190. ;----------------------------------------------------------------------------
  191. ;----------------------------------------------------------------------------
  192. ;   SEARCH_FTYPE determines the type of a file by examining its extension.
  193. ; ENTRY:
  194. ;   BX    --     dma buffer containing filename
  195. ; EXIT:
  196. ;   AL     --     file code, as given in search header
  197. ;---------------
  198. comext  db      ".COM",0
  199. exeext  db      ".EXE",0
  200. Search_Ftype PROC NEAR
  201.         public Search_Ftype
  202. push DI
  203. mov AL, search_file_not_found ; find the end of the filename
  204. mov DI, BX
  205.         add     si,Find_Buf_Pname
  206. mov CX, fname_max_len
  207. cld
  208. repnz scasb ; search for the terminating null
  209. jnz ftype_exit ; weird... no null byte at end
  210. ;
  211. ; Scan backwards to find the start of the extension
  212. ;
  213.         dec     di                              ; point back to null
  214.         mov     cx, 5                           ; . + E + X + T + null
  215.         std                                     ; scan back
  216.         mov     al, '.'
  217.         repnz   scasb
  218.         jnz     ftype_exit                      ; must not be any extension
  219.         inc     di                              ; point to start of extension
  220.         cld
  221. ;
  222. ; Compare .COM
  223. ;
  224. mov si,offset comext
  225. mov ax,di
  226. cmpsw
  227. jnz ftype_exe
  228. cmpsw
  229. jnz ftype_exe
  230. mov AL, search_com ; success!
  231. jmp short ftype_exit
  232. ;
  233. ; Compare .EXE
  234. ;
  235. ftype_exe: ; still looking... now for '.exe'
  236. mov di,ax
  237. mov si,offset exeext
  238. cmpsw
  239. jnz ftype_fail
  240. cmpsw
  241. jnz ftype_fail
  242. mov AL, search_exe ; success!
  243. jmp short ftype_exit
  244. ftype_fail: ; file doesn't match what we need
  245. mov al,search_file_not_found
  246. ftype_exit:
  247. pop DI
  248. ret
  249. Search_Ftype endp
  250. ;----------------------------------------------------------------------------
  251. ;
  252. ; Find_Comspec_In_Environment - find the beginning of the COMSPEC string
  253. ;       Entry : DS = DATA
  254. ;               ES = PSP
  255. ;       Exit  : ES:DI => start of Comspec path
  256. ;       
  257. FIND_COMSPEC_IN_environment PROC NEAR
  258.         public Find_Comspec_In_Environment
  259.         lea     si,Comspec_str
  260. mov     cx,Comspec_str_size ; cx = length of name
  261.         jmp     short Find_in_Environment
  262. Find_Comspec_in_Environment        endp
  263. ;----------------------------------------------------------------------------
  264. ;
  265. ; Find_Path_In_Environment - find the beginning of the PATH string
  266. ;       Entry : DS = DATA
  267. ;               ES = PSP
  268. ;       Exit  : ES:DI => start of Path directory list
  269. ;       
  270. FIND_PATH_IN_environment PROC NEAR
  271.         public Find_Path_In_Environment
  272.         lea     si,Path_str
  273. mov     cx,Path_str_size ; cx = length of name
  274. ; fall through to following
  275. Find_Path_in_Environment        endp
  276. ; Find_In_Environment - locate a given string in the environment
  277. ;        
  278. ; Input :       SI = name to find in environment
  279. ;               CX = length of name
  280. ;               DS = DATA
  281. ;               ES = PSP segment
  282. ;
  283. ; Output: ES:DI points to the arguments in the environment
  284. ;   carry is set if name not found
  285. ;
  286. Find_in_Environment PROC NEAR
  287.         public Find_In_Environment
  288. cld
  289.         xor     di,di
  290.         mov     ax,es:[di].PDB_Environ
  291.         or      ax,ax                          ; is there an environment?
  292.         jz      find_nf_exit                   ; no, quit now
  293.         mov     es,ax
  294.         assume  es:nothing        
  295. find1:
  296.         push    si
  297.         push    cx                              ; save starting values
  298. find11:
  299. ifdef dbcs
  300. lodsb
  301. call IsDBCSLeadByte
  302. jz notkanj3
  303. dec si
  304. lodsw
  305. inc di
  306. inc di
  307. cmp ax,es:[di-2]
  308. jnz find12
  309. dec cx
  310. loop find11
  311. jmp short find12
  312. notkanj3:
  313. inc di
  314. cmp al,es:[di-1]
  315. jnz find12
  316. loop find11
  317. else    ;dbcs
  318.         repe cmpsb   
  319. endif   ;dbcs
  320. find12:
  321.         pop     dx
  322.         pop     si                              ; clear stack
  323. jz      find_exit
  324.         dec     di
  325. xor al,al ; scan for a nul
  326. mov cx,100h                         ; arbitrary size 
  327. repnz scasb
  328. cmp byte ptr es:[di],0              ; check for trailing null
  329.         mov     cx,dx                           ; original count back in CX
  330. jnz find1
  331. find_nf_exit:
  332.         stc ; indicate not found
  333. find_exit:
  334. ret
  335. Find_in_environment endp
  336. CODE    ends
  337.         end