Source code of Windows XP (NT5)
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.

431 lines
10 KiB

  1. PAGE ,132
  2. TITLE DXFIND.ASM -- Dos Extender Find File Routine
  3. ; Copyright (c) Microsoft Corporation 1988-1991. All Rights Reserved.
  4. ;***********************************************************************
  5. ;
  6. ; DXFIND.ASM -- Dos Extender Find File Routine
  7. ;
  8. ;-----------------------------------------------------------------------
  9. ;
  10. ; This module provides the locate file logic for the 286 DOS Extender.
  11. ;
  12. ;-----------------------------------------------------------------------
  13. ;
  14. ; 09/27/89 jimmat Original version -- considerable code taken from
  15. ; old GetChildName routine in dxinit.asm.
  16. ;
  17. ;***********************************************************************
  18. .286p
  19. ; -------------------------------------------------------
  20. ; INCLUDE FILE DEFINITIONS
  21. ; -------------------------------------------------------
  22. .xlist
  23. .sall
  24. include segdefs.inc
  25. include gendefs.inc
  26. .list
  27. ; -------------------------------------------------------
  28. ; GENERAL SYMBOL DEFINITIONS
  29. ; -------------------------------------------------------
  30. ; -------------------------------------------------------
  31. ; EXTERNAL SYMBOL DEFINITIONS
  32. ; -------------------------------------------------------
  33. extrn strcpy:NEAR
  34. extrn toupper:NEAR
  35. ; -------------------------------------------------------
  36. ; DATA SEGMENT DEFINITIONS
  37. ; -------------------------------------------------------
  38. DXDATA segment
  39. extrn segPSP:WORD
  40. extrn rgbXfrBuf1:BYTE
  41. DXDATA ends
  42. ; -------------------------------------------------------
  43. ; CODE SEGMENT VARIABLES
  44. ; -------------------------------------------------------
  45. DXCODE segment
  46. szPath db 'PATH',0
  47. szWindir db 'WINDIR',0
  48. DXCODE ends
  49. ; -------------------------------------------------------
  50. subttl Find File Routine
  51. page
  52. ; -------------------------------------------------------
  53. ; FIND FILE ROUTINE
  54. ; -------------------------------------------------------
  55. DXCODE segment
  56. assume cs:DXCODE
  57. ; -------------------------------------------------------
  58. ; FindFile -- This routine is used to locate a particular file.
  59. ; If successful, this routine will setup the buffer in rgbXfrBuf1
  60. ; at offset EXEC_PROGNAME with the string for the file name that
  61. ; can be used in a DOS open call.
  62. ;
  63. ; This routine searches for the file in the following sequence:
  64. ;
  65. ; 1) If the file name contains a relative or complete path
  66. ; component, only look for that particular file,
  67. ;
  68. ; otherwise:
  69. ;
  70. ; 1) Look int the environment for a WINDIR= variable, and if
  71. ; found, check that directory first.
  72. ; 2) Look in the directory the dos extender was loaded from
  73. ; 3) Look in the current directory
  74. ; 4) Look in all directories in the PATH environment variable
  75. ;
  76. ; NOTE: This routine must be called in real mode!
  77. ;
  78. ; Input: RELOC_BUFFER has the file name to search for.
  79. ; EXEC_DXNAME has the complete path the dos extender
  80. ; Output: EXEC_PROGNAME has complete path to child program.
  81. ; Errors: returns CY set if unable to find child
  82. ; Uses: All registers preserved
  83. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  84. public FindFile
  85. FindFile proc near
  86. pusha
  87. push ds
  88. push es
  89. push ds
  90. pop es
  91. assume es:DGROUP
  92. ; If the base file name contains a ':' '\' or '/', then we'll see if the
  93. ; file can be found with that name. This isn't exactly the way Windows wants
  94. ; us to search for kernel, but allows a user to specify a relative or complete
  95. ; path on the command line. If we get run for Windows/286 pMode, the base
  96. ; child name will not include any of these characters, so we will not make
  97. ; this check.
  98. mov si,offset RELOC_BUFFER
  99. @@: lodsb
  100. or al,al
  101. jz fndf20 ;no path characters, go do other search
  102. cmp al,':'
  103. jz fndf10
  104. cmp al,'\'
  105. jz fndf10
  106. cmp al,'/'
  107. jnz @b
  108. ; The name seems to include a path component. We just want to look for that
  109. ; file, and only that file.
  110. fndf10: mov si,offset RELOC_BUFFER
  111. mov di,offset EXEC_PROGNAME
  112. mov dx,di
  113. call strcpy
  114. mov ax,4300h ;use get file attributes to check
  115. int 21h
  116. jmp fndf90 ;found it or not, either way we're done
  117. ; The file name doesn't include a path component. If we were run for pMode
  118. ; Windows, the environment should include a WINDIR= entry that points to
  119. ; the Windows directory. Look for this env variable, and check that directory
  120. ; first.
  121. fndf20:
  122. push es ;look for the
  123. push cs ;WINDIR= env variable
  124. pop es
  125. assume es:NOTHING
  126. mov di,offset DXCODE:szWindir
  127. call GetEnv
  128. pop es
  129. assume ds:NOTHING,es:DGROUP
  130. jnz fndf_dosx_dir
  131. ; Found WINDIR, copy over the path name, add child name and search
  132. mov di,offset EXEC_PROGNAME ;copy WINDIR path
  133. mov dx,di
  134. call strcpy
  135. cmp byte ptr es:[di-1],'\' ;add trailing \ if necessary
  136. jz @f
  137. mov byte ptr es:[di],'\'
  138. inc di
  139. @@:
  140. push es ;ds back to DGROUP
  141. pop ds
  142. assume ds:DGROUP
  143. mov si,offset RELOC_BUFFER ;add child name
  144. call strcpy
  145. mov ax,4300h ;use get file attributes to check
  146. int 21h
  147. jc fndf_dosx_dir ;no there, go do next check
  148. jmp fndf90 ;found it!
  149. ; Next, we try looking in the directory that the Dos Extender was loaded
  150. ; from. Start with the complete path to the Dos Extender program file.
  151. fndf_dosx_dir:
  152. push es
  153. pop ds
  154. assume ds:DGROUP
  155. mov si,offset EXEC_DXNAME
  156. mov di,offset EXEC_PROGNAME
  157. mov dx,di
  158. call strcpy
  159. ; Now, search backward from the end of the string until we find the
  160. ; first backslash or colon. This will take us back past the file name
  161. ; and leave us with the raw path.
  162. fndf24: dec di
  163. cmp di,dx ;check if we have gone back past the start
  164. ; of the string. (DX still has the address
  165. ; of the start of the buffer from above)
  166. jb fndf_cd ;and if so skip this part as the path is null.
  167. mov al,es:[di]
  168. cmp al,':'
  169. jz fndf26
  170. cmp al,'\'
  171. jnz fndf24
  172. ; Add the file name string onto the raw path and see if the file exists.
  173. fndf26: inc di
  174. mov si,offset RELOC_BUFFER
  175. call strcpy
  176. mov ax,4300h ;use get file attributes to check
  177. int 21h
  178. jc fndf_cd
  179. jmp fndf90
  180. ; We didn't find the file in the same directory as the Extender itself.
  181. ; Now, try looking for the file in the current directory!
  182. fndf_cd:
  183. mov di,offset EXEC_PROGNAME ;build current directory path string
  184. dossvc 19h
  185. add al,'A'
  186. stosb ;drive letter
  187. mov ax,'\:'
  188. stosw
  189. xor dl,dl
  190. mov si,di
  191. dossvc 47h ;current directory
  192. mov al,es:[di] ;check if it's the root
  193. or al,al ;empty string?
  194. jz short fndf_cd_cpy ;yes, don't add another '\'
  195. @@: lodsb ;find end of string
  196. or al,al
  197. jnz @b
  198. mov byte ptr [si-1],'\' ;add ending \
  199. fndf_cd_cpy:
  200. mov di,si ;add base child name
  201. mov si,offset RELOC_BUFFER
  202. call strcpy
  203. mov dx,offset EXEC_PROGNAME ;use get file attributes to check
  204. mov ax,4300h
  205. int 21h
  206. jc fndf30
  207. jmp short fndf90
  208. ; We didn't find it in the current directory, look at the PATH
  209. ; environment variable and see if the file can be found in any of
  210. ; its directories. First off, search for the PATH environment
  211. ; string.
  212. fndf30:
  213. push es
  214. mov di,offset DXCODE:szPath ;point ES:DI to path str
  215. push cs
  216. pop es
  217. assume es:NOTHING
  218. call GetEnv ;find the path env var
  219. assume ds:NOTHING
  220. pop es
  221. assume es:DGROUP
  222. jnz fndf80 ;Z flag set if FOUND
  223. ; We are pointing at the beginning of the path environment variable. We need
  224. ; to loop for each directory specified to see if we can find the file in
  225. ; that directory.
  226. mov bx,ds ;keep env segment in BX
  227. fndf40: mov ds,bx ;environment segment to DS
  228. assume ds:NOTHING
  229. mov al,ds:[si]
  230. or al,al ;check for end of path variable.
  231. jz fndf80 ;if so, we didn't find any directory with
  232. ; the desired file in it.
  233. mov di,offset EXEC_PROGNAME
  234. fndf42: lods byte ptr [si]
  235. cmp al,';' ;is it the separator between strings in
  236. jz fndf52 ; the environment variable?
  237. or al,al ;is it the 0 at the end of the environment
  238. jz fndf50 ; string?
  239. stos byte ptr [di]
  240. jmp fndf42
  241. fndf50: dec si
  242. fndf52: push si ;save pointer to start of next string
  243. mov al,'\'
  244. cmp al,byte ptr es:[di-1] ;dir name already end with \ (root dir?)
  245. jnz fndf54
  246. dec di ; yes, don't make it two \'s
  247. fndf54: stos byte ptr [di]
  248. mov si,offset RELOC_BUFFER ;pointer to file base name
  249. mov ax,es ;put our data segment address in DS
  250. mov ds,ax
  251. assume ds:DGROUP
  252. call strcpy ;append file base name to path
  253. mov ax,4300h ;use get file attributes to check
  254. int 21h
  255. pop si ;restore pointer to start of next string
  256. jc fndf40
  257. jmp short fndf90
  258. ; Unable to find the file
  259. fndf80: stc
  260. ; Finished, successful or not
  261. fndf90:
  262. pop es
  263. pop ds
  264. popa
  265. ret
  266. FindFile endp
  267. ; -------------------------------------------------------
  268. ; GetEnv -- This routine searches the environment for a
  269. ; specific variable.
  270. ;
  271. ; Input: ES:DI - far pointer to wanted variable name
  272. ; Output: DS:SI - far pointer to variable value string
  273. ; Errors: return Z true if variable located
  274. ; Uses: DS:SI modified, all else preserved
  275. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  276. public GetEnv
  277. GetEnv proc near
  278. push ax
  279. push dx
  280. push di
  281. ; Point DS:SI to our environment block
  282. mov ds,segPSP
  283. assume ds:PSPSEG
  284. mov ds,segEnviron
  285. xor si,si
  286. assume ds:NOTHING
  287. ; See if DS:SI is pointing at desired environment variable
  288. mov dx,di ;keep var name offset in dx
  289. gete10:
  290. cmp byte ptr es:[di],0 ;at end of variable name?
  291. jz gete50 ; yes, go check '=' & optional blanks
  292. gete20:
  293. lodsb ;get variable char
  294. call toupper ;just in case...
  295. cmp al,es:[di] ;match desired name so far?
  296. jnz gete30 ; no, go find the next var name
  297. inc di ;bump var pointer
  298. jmp short gete10 ; and keep on checking
  299. gete30:
  300. mov di,dx ;reset source name pointer
  301. or al,al ;already at end of this env var?!
  302. jz gete35
  303. @@: lodsb
  304. or al,al ;find next environment var name
  305. jnz @b
  306. gete35:
  307. cmp byte ptr ds:[si],0 ;at end of environment?
  308. jz gete80 ; yes, go fail the call
  309. jmp short gete10 ; no, try try again
  310. ; Found the env variable, now skip the '=' and any spaces
  311. gete50:
  312. cmp byte ptr ds:[si],'=' ;when we get here, better be pointing
  313. jnz gete30 ; at an '='
  314. inc si
  315. @@: cmp byte ptr ds:[si],' ' ;skip any optional blanks
  316. jnz @f
  317. inc si
  318. jmp short @b
  319. @@:
  320. xor ax,ax ;set the Z flag
  321. jmp short @f
  322. gete80:
  323. or ax,si ;pretty sure this clears Z
  324. @@:
  325. pop di
  326. pop dx
  327. pop ax
  328. ret
  329. GetEnv endp
  330. ; -------------------------------------------------------
  331. DXCODE ends
  332. ;****************************************************************
  333. end