]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/DIR2.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / DIR2.ASM
1 ; SCCSID = @(#)dir2.asm 1.2 85/07/23
2 ; SCCSID = @(#)dir2.asm 1.2 85/07/23
3 TITLE DIR2 - Directory and path cracking
4 NAME Dir2
5 ; Main Path cracking routines, low level search routines and device
6 ; name detection routines
7 ;
8 ; GETPATH
9 ; GetPathNoSet
10 ; CHKDEV
11 ; ROOTPATH
12 ; FINDPATH
13 ; StartSrch
14 ; MatchAttributes
15 ; DEVNAME
16 ; Build_device_ent
17 ; Validate_CDS
18 ; CheckThisDevice
19 ;
20 ; Revision history:
21 ;
22 ; A000 version 4.00 Jan. 1988
23 ; A001 PTM 3564 -- search using fastopen
24
25 ;
26 ; get the appropriate segment definitions
27 ;
28 .xlist
29 include dosseg.asm
30
31 CODE SEGMENT BYTE PUBLIC 'CODE'
32 ASSUME SS:DOSGROUP,CS:DOSGROUP
33
34 .xcref
35 include dossym.inc
36 include devsym.inc
37 include fastopen.inc ;DOS 3.3
38 .cref
39 .list
40
41 asmvar Kanji
42
43 i_need NoSetDir,BYTE
44 i_need EntFree,WORD
45 i_need DirStart,WORD
46 i_need LastEnt,WORD
47 i_need WFP_START,WORD
48 i_need CURR_DIR_END,WORD
49 i_need CurBuf,DWORD
50 i_need THISCDS,DWORD
51 i_need Attrib,BYTE
52 i_need SAttrib,BYTE
53 i_need VolID,BYTE
54 i_need Name1,BYTE
55 i_need ThisDPB,DWORD
56 i_need EntLast,WORD
57 i_need Creating,BYTE
58 i_need NULDEV,DWORD
59 i_need DEVPT,DWORD
60 i_need DEVFCB,BYTE
61 i_need ALLOWED,BYTE
62 i_need EXTERR_LOCUS,BYTE
63 I_need FastOpenFlg,BYTE ;DOS 3.3
64 I_need FastOpenTable,BYTE ;DOS 3.3
65 I_need Dir_Info_Buff,BYTE ;DOS 3.3
66 I_need FastOpen_Ext_Info,BYTE ;DOS 3.3
67 I_need CLUSNUM,WORD ;DOS 3.3
68 I_need Next_Element_Start,WORD ;DOS 3.3
69 I_need HIGH_SECTOR,WORD ;AN000;>32mb
70 I_need DOS34_FLAG,WORD ;AN000;>32mb
71
72
73 Break <GETPATH -- PARSE A WFP>
74
75 ; Inputs:
76 ; [WFP_START] Points to WFP string ("d:\" must be first 3 chars, NUL
77 ; terminated; d:/ (note forward slash) indicates a real device).
78 ; [CURR_DIR_END] Points to end of Current dir part of string
79 ; ( = -1 if current dir not involved, else
80 ; Points to first char after last "/" of current dir part)
81 ; [THISCDS] Points to CDS being used
82 ; [SATTRIB] Is attribute of search, determines what files can be found
83 ; [NoSetDir] set
84 ; [THISDPB] set to DPB if disk otherwise garbage.
85 ; Function:
86 ; Crack the path
87 ; Outputs:
88 ; Sets EXTERR_LOCUS = errLOC_Disk if disk file
89 ; Sets EXTERR_LOCUS = errLOC_Unk if char device
90 ; ID1 field of [THISCDS] updated appropriately
91 ; [ATTRIB] = [SATTRIB]
92 ; ES:BP Points to DPB
93 ; Carry set if bad path
94 ; SI Points to path element causing failure
95 ; Zero set
96 ; [DIRSTART],[DIRSEC],[CLUSNUM], and [CLUSFAC] are set up to
97 ; start a search on the last directory
98 ; CL is zero if there is a bad name in the path
99 ; CL is non-zero if the name was simply not found
100 ; [ENTFREE] may have free spot in directory
101 ; [NAME1] is the name.
102 ; CL = 81H if '*'s or '?' in NAME1, 80H otherwise
103 ; Zero reset
104 ; File in middle of path or bad name in path or attribute mismatch
105 ; or path too long or malformed path
106 ; ELSE
107 ; [CurBuf] = -1 if root directory
108 ; [CURBUF] contains directory record with match
109 ; [CURBUF+2]:BX Points into [CURBUF] to start of entry
110 ; [CURBUF+2]:SI Points into [CURBUF] to dir_first field for entry
111 ; AH = device ID
112 ; bit 7 of AH set if device SI and BX
113 ; will point DOSGROUP relative The firclus
114 ; field of the device entry contains the device pointer
115 ; [NAME1] Has name looked for
116 ; If last element is a directory zero is set and:
117 ; [DIRSTART],[SECCLUSPOS],[DIRSEC],[CLUSNUM], and [CLUSFAC]
118 ; are set up to start a search on it.
119 ; unless [NoSetDir] is non zero in which case the return is
120 ; like that for a file (except for zero flag)
121 ; If last element is a file zero is reset
122 ; [DIRSEC],[CLUSNUM],[CLUSFAC],[NXTCLUSNUM],[SECCLUSPOS],
123 ; [LASTENT], [ENTLAST] are set to continue search of last
124 ; directory for furthur matches on NAME1 via the NEXTENT
125 ; entry point in FindEntry (or GETENT entry in GETENTRY in
126 ; which case [NXTCLUSNUM] and [SECCLUSPOS] need not be valid)
127 ; DS preserved, Others destroyed
128
129 procedure GETPATH,near
130 DOSAssume CS,<DS>,"GetPath"
131 ASSUME ES:NOTHING
132
133 MOV WORD PTR [CREATING],0E500H ; Not Creating, not DEL *.*
134
135 ;Same as GetPath only CREATING and DELALL already set
136 entry GetPathNoSet
137 MOV [EXTERR_LOCUS],errLOC_Disk
138 MOV WORD PTR CurBuf,-1 ; initial setting
139 ;
140 ; See if the input indicates a device that has already been detected. If so,
141 ; go build the guy quickly. Otherwise, let findpath find the device.
142 ;
143 MOV DI,Wfp_Start ; point to the beginning of the name
144 CMP WORD PTR [DI+1],'\' SHL 8 + ':'
145 JZ CrackIt
146 ;
147 ; Let ChkDev find it in the device list
148 ;
149 ADD DI,3
150 MOV SI,DI ; let CHKDEV see the original name
151 CALL CHKDEV
152 JC InternalError
153 Build_devJ:
154 MOV AL,SAttrib
155 MOV Attrib,AL
156 MOV [EXTERR_LOCUS],errLOC_Unk ; In the particular case of
157 ; "finding" a char device
158 ; set LOCUS to Unknown. This makes
159 ; certain idiotic problems reported
160 ; by a certain 3 letter OEM go away.
161 ;
162 ; Take name in name1 and pack it back into where wfp_start points. This
163 ; guarantees wfp_start pointing to a canonical representation of a device.
164 ; We are allowed to do this as GetPath is *ALWAYS* called before entering a
165 ; wfp into the share set.
166 ;
167 ; We copy chars from name1 to wfp_start remembering the position of the last
168 ; non-space seen +1. This position is kept in DX.
169 ;
170 Context ES
171 mov si,offset DOSGroup:Name1
172 mov di,wfp_start
173 mov dx,di
174 mov cx,8 ; 8 chars in device name
175 MoveLoop:
176 lodsb
177 stosb
178 cmp al," "
179 jz nosave
180 IF DBCS ;AN000;;
181 ; cmp al,81h ;AN000;; 2/23/KK
182 ; jne notKanji ;AN000;; 2/23/KK
183 ; cmp cx,1 ;AN000; 2/23/KK
184 ; je notKanji ;AN000; 2/23/KK
185 ; cmp byte ptr [si],40h ;AN000; 2/23/KK
186 ; jne notKanji ;AN000;; 2/23/KK
187 ; lodsb ;AN000;; 2/23/KK
188 ; stosb ;AN000;; 2/23/KK
189 ; dec cx ;AN000;; 2/23/KK
190 ; jmp nosave ;AN000;; 2/23/KK
191 ;notKanji: ;AN000;; 2/23/KK
192 ENDIF
193 mov dx,di
194 NoSave:
195 loop MoveLoop
196 ;
197 ; DX is the position of the last seen non-space + 1. We terminate the name
198 ; at this point.
199 ;
200 mov di,dx
201 mov byte ptr [di],0 ; end of string
202 invoke Build_device_ent ; Clears carry sets zero
203 INC AL ; reset zero
204 return
205
206 assume es:nothing
207
208 InternalError:
209 JMP InternalError ; freeze
210
211 ;
212 ; Start off at the correct spot. Optimize if the current dir part is valid.
213 ;
214 CrackIt:
215 MOV SI,[CURR_DIR_END] ; get current directory pointer
216 CMP SI,-1 ; valid?
217 JNZ LOOK_SING ; Yes, use it.
218 LEA SI,[DI+3] ; skip D:\
219 LOOK_SING:
220 Assert ISDPB,<<WORD PTR THISDPB+2>,<WORD PTR THISDPB>>,"Crackit"
221 MOV Attrib,attr_directory+attr_system+attr_hidden
222 ; Attributes to search through Dirs
223 LES DI,[THISCDS]
224 MOV AX,-1
225 MOV BX,ES:[DI.curdir_ID]
226 MOV SI,[CURR_DIR_END]
227 ;
228 ; AX = -1
229 ; BX = cluster number of current directory. THis number is -1 if the media
230 ; has been uncertainly changed.
231 ; SI = offset in DOSGroup into path to end of current directory text. This
232 ; may be -1 if no current directory part has been used.
233 ;
234 CMP SI,AX ; if Current directory is not part
235 JZ NO_CURR_D ; then we must crack from root
236 CMP BX,AX ; is the current directory cluster valid
237
238 ; DOS 3.3 6/25/86
239 JZ NO_CURR_D ; no, crack form the root
240 TEST [FastOpenFlg],FastOpen_Set ; for fastopen ?
241 JZ GOT_SEARCH_CLUSTER ; no
242 PUSH ES ; save registers
243 PUSH DI
244 PUSH CX
245 PUSH [SI-1] ; save \ and 1st char of next element
246 PUSH SI
247 PUSH BX
248
249 MOV BYTE PTR [SI-1],0 ; call fastopen to look up cur dir info
250 MOV SI,[Wfp_Start]
251 MOV BX,OFFSET DOSGROUP:FastOpenTable
252 MOV DI,OFFSET DOSGROUP:Dir_Info_Buff
253 MOV CX,OFFSET DOSGROUP:FastOpen_Ext_Info
254 MOV AL,FONC_look_up
255 PUSH DS
256 POP ES
257 CALL DWORD PTR [BX.FASTOPEN_NAME_CACHING]
258 JC GO_Chk_end1 ;fastopen not installed, or wrong drive. Go to Got_Srch_cluster
259 CMP BYTE PTR [SI],0 ;fastopen has current dir info?
260 JE GO_Chk_end ;yes. Go to got_serch_cluster
261 stc
262 jmp short GO_Chk_end ;Go to No_Curr_D
263 GO_Chk_end1:
264 clc
265 GO_Chk_end: ; restore registers
266 POP BX
267 POP SI
268 POP [SI-1]
269 POP CX
270 POP DI
271 POP ES
272 JNC GOT_SEARCH_CLUSTER ; crack based on cur dir
273
274 ; DOS 3.3 6/25/86
275 ;
276 ; We must cract the path beginning at the root. Advance pointer to beginning
277 ; of path and go crack from root.
278 ;
279 NO_CURR_D:
280 MOV SI,[WFP_START]
281 LEA SI,[SI+3] ; Skip "d:/"
282 LES BP,[THISDPB] ; Get ES:BP
283 JMP ROOTPATH
284 ;
285 ; We are able to crack from the current directory part. Go set up for search
286 ; of specified cluster.
287 ;
288 GOT_SEARCH_CLUSTER:
289 LES BP,[THISDPB] ; Get ES:BP
290 invoke SETDIRSRCH
291 JC SETFERR
292 JMP FINDPATH
293
294 SETFERR:
295 XOR CL,CL ; set zero
296 STC
297 Return
298
299 EndProc GETPATH
300
301 ; Check to see if the name at DS:DI is a device. Returns carry set if not a
302 ; device.
303 ; Blasts CX,SI,DI,AX,BX
304
305 Procedure ChkDev,NEAR
306 ASSUME ES:Nothing,DS:NOTHING
307
308 MOV SI,DI
309 MOV DI,SS
310 MOV ES,DI
311 ASSUME ES:DOSGroup ; Now here is where ES is DOSGroup
312
313 MOV DI,OFFSET DOSGROUP:NAME1
314 MOV CX,9
315 TESTLOOP:
316 invoke GETLET
317 IF DBCS ;AN000;
318 invoke Testkanj ;AN000;; 2/13/KK
319 jz Notkanja ;AN000;; 2/13/KK
320 stosb ;AN000;; Skip second byte 2/13/KK
321 dec cx ;AN000;; 2/13/KK
322 jcxz notdev ;AN000;; 2/13/KK
323 lodsb ;AN000;; 2/13/KK
324 jmp short stowit ;AN000;; 2/13/KK
325 Notkanja: ;AN000;
326 ENDIF ;AN000;
327 CMP AL,'.'
328 JZ TESTDEVICE
329 invoke PATHCHRCMP
330 JZ NOTDEV
331 OR AL,AL
332 JZ TESTDEVICE
333 stowit:
334 STOSB
335 LOOP TESTLOOP
336 NOTDEV:
337 STC
338 return
339
340 TESTDEVICE:
341 ADD CX,2
342 MOV AL,' '
343 REP STOSB
344 MOV AX,SS
345 MOV DS,AX
346 invoke DEVNAME
347 return
348 EndProc ChkDev
349
350 Break <ROOTPATH, FINDPATH -- PARSE A PATH>
351
352 ; Inputs:
353 ; Same as FINDPATH but,
354 ; SI Points to asciz string of path which is assumed to start at
355 ; the root (no leading '/').
356 ; Function:
357 ; Search from root for path
358 ; Outputs:
359 ; Same as FINDPATH but:
360 ; If root directory specified, [CURBUF] and [NAME1] are NOT set, and
361 ; [NoSetDir] is ignored.
362
363 procedure ROOTPATH,near
364
365 DOSAssume CS,<DS>,"RootPath"
366 ASSUME ES:NOTHING
367
368 invoke SETROOTSRCH
369 CMP BYTE PTR [SI],0
370 JNZ FINDPATH
371
372 ; Root dir specified
373 MOV AL,SAttrib
374 MOV Attrib,AL
375 XOR AH,AH ; Sets "device ID" byte, sets zero
376 ; (dir), clears carry.
377 return
378
379 ; Inputs:
380 ; [ATTRIB] Set to get through directories
381 ; [SATTRIB] Set to find last element
382 ; ES:BP Points to DPB
383 ; SI Points to asciz string of path (no leading '/').
384 ; [SECCLUSPOS] = 0
385 ; [DIRSEC] = Phys sec # of first sector of directory
386 ; [CLUSNUM] = Cluster # of next cluster
387 ; [CLUSFAC] = Sectors per cluster
388 ; [NoSetDir] set
389 ; [CURR_DIR_END] Points to end of Current dir part of string
390 ; ( = -1 if current dir not involved, else
391 ; Points to first char after last "/" of current dir part)
392 ; [THISCDS] Points to CDS being used
393 ; [CREATING] and [DELALL] set
394 ; Function:
395 ; Parse path name
396 ; Outputs:
397 ; ID1 field of [THISCDS] updated appropriately
398 ; [ATTRIB] = [SATTRIB]
399 ; ES:BP Points to DPB
400 ; [THISDPB] = ES:BP
401 ; Carry set if bad path
402 ; SI Points to path element causing failure
403 ; Zero set
404 ; [DIRSTART],[DIRSEC],[CLUSNUM], and [CLUSFAC] are set up to
405 ; start a search on the last directory
406 ; CL is zero if there is a bad name in the path
407 ; CL is non-zero if the name was simply not found
408 ; [ENTFREE] may have free spot in directory
409 ; [NAME1] is the name.
410 ; CL = 81H if '*'s or '?' in NAME1, 80H otherwise
411 ; Zero reset
412 ; File in middle of path or bad name in path
413 ; or path too long or malformed path
414 ; ELSE
415 ; [CURBUF] contains directory record with match
416 ; [CURBUF+2]:BX Points into [CURBUF] to start of entry
417 ; [CURBUF+2]:SI Points to fcb_FIRCLUS field for entry
418 ; [NAME1] Has name looked for
419 ; AH = device ID
420 ; bit 7 of AH set if device SI and BX
421 ; will point DOSGROUP relative The firclus
422 ; field of the device entry contains the device pointer
423 ; If last element is a directory zero is set and:
424 ; [DIRSTART],[SECCLUSPOS],[DIRSEC],[CLUSNUM], and [CLUSFAC]
425 ; are set up to start a search on it,
426 ; unless [NoSetDir] is non zero in which case the return is
427 ; like that for a file (except for zero flag)
428 ; If last element is a file zero is reset
429 ; [DIRSEC],[CLUSNUM],[CLUSFAC],[NXTCLUSNUM],[SECCLUSPOS],
430 ; [LASTENT], [ENTLAST] are set to continue search of last
431 ; directory for furthur matches on NAME1 via the NEXTENT
432 ; entry point in FindEntry (or GETENT entry in GETENTRY in
433 ; which case [NXTCLUSNUM] and [SECCLUSPOS] need not be valid)
434 ; Destroys all other registers
435
436 entry FINDPATH
437 DOSAssume CS,<DS>,"FindPath"
438 ASSUME ES:NOTHING
439
440 Assert ISDPB,<ES,BP>,"FindPath"
441 PUSH ES ; Save ES:BP
442 PUSH SI
443 MOV DI,SI
444 MOV CX,[DIRSTART] ; Get start clus of dir being searched
445 CMP [CURR_DIR_END],-1
446 JZ NOIDS ; No current dir part
447 CMP DI,[CURR_DIR_END]
448 JNZ NOIDS ; Not to current dir end yet
449 LES DI,[THISCDS]
450 MOV ES:[DI.curdir_ID],CX ; Set current directory currency
451 NOIDS:
452 ;
453 ; Parse the name off of DS:SI into NAME1. AL = 1 if there was a meta
454 ; character in the string. CX,DI may be destroyed.
455 ;
456 ; invoke NAMETRANS
457 ; MOV CL,AL
458 ;
459 ; The above is the slow method. The name has *already* been munged by
460 ; TransPath so no special casing needs to be done. All we do is try to copy
461 ; the name until ., \ or 0 is hit.
462 ;
463 MOV AX,SS
464 MOV ES,AX
465 MOV DI,OFFSET DOSGroup:Name1
466 MOV AX,' '
467 STOSB
468 STOSW
469 STOSW
470 STOSW
471 STOSW
472 STOSW
473 MOV DI,OFFSET DOSGroup:Name1
474 XOR AH,AH ; bits for CL
475 IF DBCS ;AN000;
476 ;-------------------------- Start of DBC;AN000;S 2/13/KK
477 XOR CL,CL ;AN000;; clear count for volume id
478 LODSB ;AN000;;IBMJ fix 9/04/86
479 CMP AL,05h ;AN000;;IBMJ fix 9/04/86
480 JNE GetNam2 ;AN000;;IBMJ fix 9/04/86
481 PUSH AX ;AN000; ;IBMJ fix 9/04/86
482 MOV AL,0E5h ;AN000;;IBMJ fix 9/04/86
483 Invoke TestKanj ;AN000;;IBMJ fix 9/04/86
484 POP AX ;AN000; ;IBMJ fix 9/04/86
485 JZ Notkanjb ;AN000; ;IBMJ fix 9/04/86
486 JMP SHORT GetNam3 ;AN000;;IBMJ fix 9/04/86
487 ;-------------------------- End of DBCS ;AN000;2/13/KK
488 ENDIF
489 GetNam:
490 INC CL ;AN000; KK incrment volid count
491 LODSB
492 IF DBCS ;AN000;
493 GetNam2: ;AN000;; 2/13/KK
494 invoke Testkanj ;AN000;; 2/13/KK
495 jz Notkanjb ;AN000;; 2/13/KK
496 GetNam3: ;AN000;; 2/13/KK
497 STOSB ;AN000;; 2/13/KK
498 INC CL ;AN000;; KK incrment volid count
499 LODSB ;AN000;; 2/13/KK
500 TEST [DOS34_FLAG],DBCS_VOLID ;AN000;; 2/13/KK
501 JZ notvol ;AN000;; 2/13/KK
502 CMP CL,8 ;AN000;; 2/13/KK
503 JNZ notvol ;AN000;; 2/13/KK
504 CMP AL,'.' ;AN000;; 2/13/KK
505 JNZ notvol ;AN000;; 2/13/KK
506 LODSB ;AN000;; 2/13/KK
507 notvol: ;AN000;
508 jmp short StoNam ;AN000;; 2/13/KK
509 Notkanjb: ;AN000;; 2/13/KK
510 ENDIF ;AN000;
511 CMP AL,'.'
512 JZ setExt
513 OR AL,AL
514 JZ GetDone
515 CMP AL,'\'
516 JZ GetDone
517 CMP AL,'?'
518 JNZ StoNam
519 OR AH,1
520 StoNam: STOSB
521 JMP GetNam
522 SetExt:
523 MOV DI,OFFSET DOSGroup:Name1+8
524 GetExt:
525 LODSB
526 IF DBCS ;AN000;
527 invoke TestKanj ;AN000;; 2/13/KK
528 jz Notkanjc ;AN000;; 2/13/KK
529 STOSB ;AN000;; 2/13/KK
530 LODSB ;AN000;; 2/13/KK
531 jmp short StoExt ;AN000;; 2/13/KK
532 Notkanjc: ;AN000;; 2/13/KK
533 ENDIF ;AN000;
534 OR AL,AL
535 JZ GetDone
536 CMP AL,'\'
537 JZ GetDone
538 CMP AL,'?'
539 JNZ StoExt
540 OR AH,1
541 StoExt: STOSB
542 JMP GetExt
543 GetDone:
544 DEC SI
545 MOV CL,AH
546
547
548 OR CL,80H
549 POP DI ; Start of this element
550 POP ES ; Restore ES:BP
551 CMP SI,DI
552 JNZ check_device
553 JMP BADPATH ; NUL parse (two delims most likely)
554 check_device:
555 PUSH SI ; Start of next element
556 MOV AL,BYTE PTR [SI]
557 OR AL,AL
558 JNZ NOT_LAST
559
560 ;
561 ; for last element of the path switch to the correct search attributes
562 ;
563 MOV BH,SAttrib
564 MOV Attrib,BH
565 NOT_LAST:
566
567 ;
568 ; check name1 to see if we have a device...
569 ;
570 PUSH ES ; Save ES:BP
571 context ES
572 invoke DevName ; blast BX
573 POP ES ; Restore ES:BP
574 ASSUME ES:NOTHING
575 JC FindFile ; Not a device
576 OR AL,AL ; Test next char again
577 JZ GO_BDEV
578 JMP FileInPath ; Device name in middle of path
579
580 GO_BDEV:
581 POP SI ; Points to NUL at end of path
582 JMP Build_devJ
583
584 FindFile:
585 ASSUME ES:NOTHING
586 ;;;; 7/28/86
587 CMP BYTE PTR [NAME1],0E5H ; if 1st char = E5
588 JNZ NOE5 ; no
589 MOV BYTE PTR [NAME1],05H ; change it to 05
590 NOE5:
591
592 ;;;; 7/28/86
593 PUSH DI ; Start of this element
594 PUSH ES ; Save ES:BP
595 PUSH CX ; CL return from NameTrans
596 ;DOS 3.3 FastOPen 6/12/86 F.C.
597
598 CALL LookupPath ; call fastopen to get dir entry
599 JNC DIR_FOUND ; found dir entry
600
601 ;DOS 3.3 FastOPen 6/12/86 F.C.
602 invoke FINDENTRY
603 DIR_FOUND:
604 POP CX
605 POP ES
606 POP DI
607 JNC LOAD_BUF
608 JMP BADPATHPOP
609
610 LOAD_BUF:
611 LDS DI,[CURBUF]
612 ASSUME DS:NOTHING
613 TEST BYTE PTR [BX+dir_attr],attr_directory
614 JNZ GO_NEXT ; DOS 3.3
615 JMP FileInPath ; Error or end of path
616 ;
617 ; if we are not setting the directory, then check for end of string
618 ;
619 GO_NEXT:
620 CMP BYTE PTR [NoSetDir],0
621 JZ SetDir
622 MOV DX,DI ; Save pointer to entry
623 MOV CX,DS
624 context DS
625 POP DI ; Start of next element
626 TEST [FastOpenFlg],FastOpen_Set ;only DOSOPEN can take advantage of
627 JZ nofast ; the FastOpen
628 TEST [FastOpenFlg],Lookup_Success ; Lookup just happened
629 JZ nofast ; no
630 MOV DI,[Next_Element_Start] ; no need to insert it again
631 nofast:
632 CMP BYTE PTR [DI],0
633 JNZ NEXT_ONE ; DOS 3.3
634 JMP SetRet ; Got it
635 NEXT_ONE:
636 PUSH DI ; Put start of next element back on stack
637 MOV DI,DX
638 MOV DS,CX ; Get back pointer to entry
639 ASSUME DS:NOTHING
640
641 SetDir:
642 MOV DX,[SI] ; Dir_first
643
644 ;DOS 3.3 FastOPen 6/12/86 F.C.
645
646 PUSH DS ; save [curbuf+2]
647 context DS ; set DS Dosgroup
648 TEST [FastOpenFlg],Lookup_Success ;
649 JZ DO_NORMAL ; fastopen not in memory or path not
650 MOV BX,DX ; not found
651 MOV DI,[CLUSNUM] ; clusnum was set in LookupPath
652 PUSH AX ; save device id (AH)
653 invoke SETDIRSRCH
654 POP AX ; restore device id (AH)
655 ADD SP,2 ; pop ds in stack
656 JMP FAST_OPEN_SKIP
657
658 DO_NORMAL:
659 ASSUME DS:NOTHING
660 POP DS ; DS = [curbuf + 2]
661 ;DOS 3.3 FastOPen 6/12/86 F.C.
662
663 SUB BX,DI ; Offset into sector of start of entry
664 SUB SI,DI ; Offset into sector of dir_first
665 PUSH BX
666 PUSH AX
667 PUSH SI
668 PUSH CX
669 PUSH WORD PTR [DI.buf_sector] ;AN000;>32mb
670 PUSH WORD PTR [DI.buf_sector+2] ;AN000;>32mb
671 MOV BX,DX
672 context DS
673 invoke SETDIRSRCH ; This uses UNPACK which might blow
674 ; the entry sector buffer
675 POP [HIGH_SECTOR]
676 POP DX
677 JC SKIP_GETB
678 MOV [ALLOWED],allowed_RETRY + allowed_FAIL
679 XOR AL,AL
680 invoke GETBUFFR ; Get the entry buffer back
681 SKIP_GETB:
682 POP CX
683 POP SI
684 POP AX
685 POP BX
686 JNC SET_THE_BUF
687 POP DI ; Start of next element
688 MOV SI,DI ; Point with SI
689 JMP SHORT BADPATH
690
691 SET_THE_BUF:
692 invoke SET_BUF_AS_DIR
693 MOV DI,WORD PTR [CURBUF]
694 ADD SI,DI ; Get the offsets back
695 ADD BX,DI
696 ; DOS 3.3 FasOpen 6/12/86 F.C.
697
698 FAST_OPEN_SKIP:
699
700 POP DI ; Start of next element
701 CALL InsertPath ; insert dir entry info
702
703 ; DOS 3.3 FasOpen 6/12/86 F.C.
704
705
706 MOV AL,[DI]
707 OR AL,AL
708 JZ SETRET ; At end
709 INC DI ; Skip over "/"
710 MOV SI,DI ; Point with SI
711 invoke PATHCHRCMP
712 JNZ find_bad_name ; oops
713 JMP FINDPATH ; Next element
714
715 find_bad_name:
716 DEC SI ; Undo above INC to get failure point
717 BADPATH:
718 XOR CL,CL ; Set zero
719 JMP SHORT BADPRET
720
721 FILEINPATH:
722 POP DI ; Start of next element
723 context DS ; Got to from one place with DS gone
724 ; DOS 3.3 FastOpen
725
726 TEST [FastOpenFlg],FastOpen_Set ; do this here is we don't want to
727 JZ NO_FAST ; device info to fastopen
728 TEST [FastOpenFlg],Lookup_Success
729 JZ NO_FAST
730 MOV DI,[Next_Element_Start] ; This takes care of one time lookup
731 ; success
732 NO_FAST:
733
734 ; DOS 3.3 FastOpen
735
736 MOV AL,[DI]
737 OR AL,AL
738 JZ INCRET
739 MOV SI,DI ; Path too long
740 JMP SHORT BADPRET
741
742 INCRET:
743 ; DOS 3.3 FasOpen 6/12/86 F.C.
744
745 CALL InsertPath ; insert dir entry info
746
747 ; DOS 3.3 FasOpen 6/12/86 F.C.
748 INC AL ; Reset zero
749 SETRET:
750 return
751
752 BADPATHPOP:
753 POP SI ; Start of next element
754 MOV AL,[SI]
755 MOV SI,DI ; Start of bad element
756 OR AL,AL ; zero if bad element is last, non-zero if path too long
757 BADPRET:
758 MOV AL,SAttrib
759 MOV Attrib,AL ; Make sure return correct
760 STC
761 return
762 EndProc ROOTPATH
763
764 Break <STARTSRCH -- INITIATE DIRECTORY SEARCH>
765
766 ; Inputs:
767 ; [THISDPB] Set
768 ; Function:
769 ; Set up a search for GETENTRY and NEXTENTRY
770 ; Outputs:
771 ; ES:BP = Drive parameters
772 ; Sets up LASTENT, ENTFREE=ENTLAST=-1, VOLID=0
773 ; Destroys ES,BP,AX
774
775 procedure StartSrch,NEAR
776 DOSAssume CS,<DS>,"StartSrch"
777 ASSUME ES:NOTHING
778
779 Assert ISDPB,<<WORD PTR THISDPB+2>,<WORD PTR THISDPB>>,"StartSrch"
780 LES BP,[THISDPB]
781 XOR AX,AX
782 MOV [LASTENT],AX
783 MOV BYTE PTR [VOLID],AL ; No volume ID found
784 DEC AX
785 MOV [ENTFREE],AX
786 MOV [ENTLAST],AX
787 return
788 EndProc StartSrch
789
790 BREAK <MatchAttributes - the final check for attribute matching>
791
792 ;
793 ; Input: [Attrib] = attribute to search for
794 ; CH = found attribute
795 ; Output: JZ <match>
796 ; JNZ <nomatch>
797 ; Registers modified: noneski
798 procedure MatchAttributes,near
799 ASSUME DS:NOTHING,ES:NOTHING
800 PUSH AX
801 MOV AL,Attrib ; AL <- SearchSet
802 NOT AL ; AL <- SearchSet'
803 AND AL,CH ; AL <- SearchSet' and FoundSet
804 AND AL,attr_all ; AL <- SearchSet' and FoundSet and Important
805 ;
806 ; the result is non-zero if an attribute is not in the search set
807 ; and in the found set and in the important set. This means that we do not
808 ; have a match. Do a JNZ <nomatch> or JZ <match>
809 ;
810 POP AX
811 return
812 EndProc MatchAttributes
813
814 Break <DevName - Look for name of device>
815
816 ; Inputs:
817 ; DS,ES:DOSGROUP
818 ; Filename in NAME1
819 ; ATTRIB set so that we can error out if looking for Volume IDs
820 ; Function:
821 ; Determine if file is in list of I/O drivers
822 ; Outputs:
823 ; Carry set if not a device
824 ; ELSE
825 ; Zero flag set
826 ; BH = Bit 7,6 = 1, bit 5 = 0 (cooked mode)
827 ; bits 0-4 set from low byte of attribute word
828 ; DEVPT = DWORD pointer to Device header of device
829 ; BX destroyed, others preserved
830
831 procedure DEVNAME,NEAR
832 DOSAssume CS,<ES,DS>,"DevName"
833
834 PUSH SI
835 PUSH DI
836 PUSH CX
837 PUSH AX
838
839 ; E5 special code
840 PUSH WORD PTR [NAME1]
841 CMP [NAME1],5
842 JNZ NOKTR
843 MOV [NAME1],0E5H
844 NOKTR:
845
846 TEST Attrib,attr_volume_id ; If looking for VOL id don't find devs
847 JNZ RET31
848 MOV SI,OFFSET DOSGROUP:NULDEV
849 LOOKIO:
850 ASSUME DS:NOTHING
851 TEST [SI.SDEVATT],DEVTYP
852 JZ SKIPDEV ; Skip block devices (NET and LOCAL)
853 MOV AX,SI
854 ADD SI,SDEVNAME
855 MOV DI,OFFSET DOSGROUP:NAME1
856 MOV CX,4 ; All devices are 8 letters
857 REPE CMPSW ; Check for name in list
858 MOV SI,AX
859 JZ IOCHK ; Found it?
860 SKIPDEV:
861 LDS SI,DWORD PTR [SI] ; Get address of next device
862 CMP SI,-1 ; At end of list?
863 JNZ LOOKIO
864 RET31: STC ; Not found
865 RETNV: MOV CX,SS
866 MOV DS,CX
867 ASSUME DS:DOSGroup
868 POP WORD PTR [NAME1]
869 POP AX
870 POP CX
871 POP DI
872 POP SI
873 RET
874
875 IOCHK:
876 ASSUME DS:NOTHING
877 MOV WORD PTR [DEVPT+2],DS ; Save pointer to device
878 MOV BH,BYTE PTR [SI.SDEVATT]
879 OR BH,0C0H
880 AND BH,NOT 020H ; Clears Carry
881 MOV WORD PTR [DEVPT],SI
882 JMP RETNV
883 EndProc DevName
884
885 BREAK <Build_device_ent - Make a Directory entry>
886
887 ; Inputs:
888 ; [NAME1] has name
889 ; BH is attribute field (supplied by DEVNAME)
890 ; [DEVPT] points to device header (supplied by DEVNAME)
891 ; Function:
892 ; Build a directory entry for a device at DEVFCB
893 ; Outputs:
894 ; BX points to DEVFCB
895 ; SI points to dir_first field
896 ; AH = input BH
897 ; AL = 0
898 ; dir_first = DEVPT
899 ; Zero Set, Carry Clear
900 ; DS,ES,BP preserved, others destroyed
901
902 procedure Build_device_ent,near
903 DOSAssume CS,<ES,DS>,"Build_Device_Ent"
904
905 MOV AX," "
906 MOV DI,OFFSET DOSGROUP:DEVFCB+8 ; Point to extent field
907 ;
908 ; Fill dir_ext
909 ;
910 STOSW
911 STOSB ; Blank out extent field
912 MOV AL,attr_device
913 ;
914 ; Fill Dir_attr
915 ;
916 STOSB ; Set attribute field
917 XOR AX,AX
918 MOV CX,10
919 ;
920 ; Fill dir_pad
921 ;
922 REP STOSW ; Fill rest with zeros
923 invoke DATE16
924 MOV DI,OFFSET DOSGROUP:DEVFCB+dir_time
925 XCHG AX,DX
926 ;
927 ; Fill dir_time
928 ;
929 STOSW
930 XCHG AX,DX
931 ;
932 ; Fill dir_date
933 ;
934 STOSW
935 MOV SI,DI ; SI points to dir_first field
936 MOV AX,WORD PTR [DEVPT]
937 ;
938 ; Fill dir_first
939 ;
940 STOSW ; Dir_first points to device
941 MOV AX,WORD PTR [DEVPT+2]
942 ;
943 ; Fill dir_size_l
944 ;
945 STOSW
946 MOV AH,BH ; Put device atts in AH
947 MOV BX,OFFSET DOSGROUP:DEVFCB
948 XOR AL,AL ; Set zero, clear carry
949 return
950 EndProc Build_device_ent
951
952 Break <ValidateCDS - given a CDS, validate the media and the current directory>
953
954 ;
955 ; ValidateCDS - Get current CDS. Splice it. Call FatReadCDS to check
956 ; media. If media has been changed, do DOS_Chdir to validate path. If
957 ; invalid, reset original CDS to root.
958 ;
959 ; Inputs: ThisCDS points to CDS of interest
960 ; SS:DI points to temp buffer
961 ; Outputs: The current directory string is validated on the appropriate
962 ; drive
963 ; ThisDPB changed
964 ; ES:DI point to CDS
965 ; Carry set if error (currently user FAILed to I 24)
966 ; Registers modified: all
967
968 Procedure ValidateCDS,NEAR
969 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
970 Public DIR2001S,DIR2001E
971 DIR2001S:
972 LocalVar Temp,WORD
973 LocalVar SaveCDS,DWORD
974 DIR2001E:
975 Enter
976 MOV Temp,DI
977 LDS SI,ThisCDS
978 MOV SaveCDSL,SI
979 MOV SaveCDSH,DS
980 EnterCrit critDisk
981 TEST [SI].curdir_flags,curdir_isnet ; Clears carry
982 JZ DoSplice
983 JMP FatFail
984 DoSplice:
985 XOR DL,DL
986 XCHG DL,NoSetDir
987 Context ES
988 Invoke FStrcpy
989 MOV SI,Temp
990 Context DS
991 Invoke Splice
992 ASSUME DS:NOTHING
993 Context DS ; FatReadCDS (ThisCDS);
994 MOV NoSetDir,DL
995 LES DI,ThisCDS
996 SaveReg <BP>
997 Invoke FatRead_CDS
998 RestoreReg <BP>
999 JC FatFail
1000 LDS SI,ThisCDS ; if (ThisCDS->ID == -1) {
1001 ASSUME DS:NOTHING
1002 CMP [SI].curdir_ID,-1
1003 JNZ RestoreCDS
1004 Context ES
1005 SaveReg <wfp_Start> ; t = wfp_Start;
1006 CMP SI,SaveCDSL ; if not spliced
1007 JNZ DoChdir
1008 MOV DI,Temp
1009 MOV wfp_Start,DI ; wfp_start = d;
1010 Invoke FStrCpy ; strcpy (d, ThisCDS->Text);
1011 DoChdir:
1012 Context DS
1013 SaveReg <<WORD PTR SAttrib>,BP> ; c = DOSChDir ();
1014 Invoke DOS_ChDir
1015 RestoreReg <BP,BX,wfp_start> ; wfp_Start = t;
1016 MOV SAttrib,BL
1017 LDS SI,SaveCDS
1018 ASSUME DS:NOTHING
1019 JNC SetCluster ; if (c == -1) {
1020 MOV WORD PTR ThisCDS,SI ; ThisCDS = TmpCDS;
1021 MOV WORD PTR ThisCDS+2,DS
1022 XOR CX,CX ; TmpCDS->text[3] = c = 0;
1023 MOV [SI+3],CL ; }
1024 SetCluster:
1025 MOV [SI].curdir_ID,-1 ; TmpCDS->ID = -1;
1026 LDS SI,ThisCDS ; ThisCDS->ID = c;
1027 TEST [SI].curdir_flags,curdir_splice ;AN000;;MS. for Join and Subst
1028 JZ setdirclus ;AN000;;MS.
1029 MOV CX,-1 ;AN000;;MS.
1030 setdirclus:
1031 MOV [SI].curdir_ID,CX ; }
1032 RestoreCDS:
1033 LES DI,SaveCDS
1034 MOV WORD PTR ThisCDS,DI
1035 MOV WORD PTR ThisCDS+2,ES
1036 CLC
1037 FatFail:
1038 LeaveCrit critDisk
1039 LES DI,SaveCDS
1040 Leave
1041 return
1042 EndProc ValidateCDS
1043
1044 Break <CheckThisDevice - Check for being a device>
1045
1046 ;
1047 ; CheckThisDevice - Examine the area at DS:SI to see if there is a valid
1048 ; device specified. We will return carry if there is a device present. The
1049 ; forms of devices we will recognize are:
1050 ;
1051 ; [path]device
1052 ;
1053 ; Note that the drive letter has *already* been removed. All other forms
1054 ; are not considered to be devices. If such a device is found we change the
1055 ; source pointer to point to the device component.
1056 ;
1057 ; Inputs: ES is DOSGroup
1058 ; DS:SI contains name
1059 ; Outputs: ES is DOSGroup
1060 ; DS:SI point to name or device
1061 ; Carry flag set if device was found
1062 ; Carry flag reset otherwise
1063 ; Registers Modified: all except ES:DI, DS
1064
1065 if FALSE
1066 Procedure CheckThisDevice,NEAR
1067 DOSAssume CS,<ES>,"CheckThisDevice"
1068 ASSUME DS:NOTHING
1069 SaveReg <DI,SI>
1070 ;
1071 ; Advance to after the final path character.
1072 ;
1073 MOV DI,SI ; remember first character
1074 PathSkip:
1075 LODSB
1076 OR AL,AL
1077 JZ FoundEnd
1078 IF DBCS ;AN000;
1079 invoke Testkanj ;AN000;; 2/13/KK
1080 jz Notkanje ;AN000;; 2/13/KK
1081 lodsb ;AN000;; 2/13/KK
1082 or al,al ;AN000;; Skip second byte 2/13/KK removed
1083 jz FoundEnd ;AN000;; 2/13/KK removed
1084 jmp Short Pathskip ;AN000;; Ignore missing second byte for now.
1085 NotKanje: ;AN000;
1086 ENDIF ;AN000;
1087 ;kanji load of next char too 2/13/KK
1088 IF Kanji
1089 kanji load of next char too
1090 ENDIF
1091 invoke PathChrCmp ; is it a path char?
1092 JNZ PathSkip
1093 MOV DI,SI
1094 JMP PathSkip
1095 FoundEnd:
1096 MOV SI,DI
1097 ;
1098 ; Parse the name
1099 ;
1100 SaveReg <DS,SI> ; preserve the source pointer
1101 invoke NameTrans ; advance DS:SI
1102 CMP BYTE PTR [SI],0 ; parse entire string?
1103 STC ; simulate a Carry return from DevName
1104 JNZ SkipSearch ; no parse. simulate a file return.
1105 Context DS
1106 Invoke DevName
1107 ASSUME DS:NOTHING
1108 SkipSearch:
1109 RestoreReg <SI,DS>
1110 ;
1111 ; DS:SI points to the beginning of the potential device. If we have a device
1112 ; then we do not change SI. If we have a file, then we reset SI back to the
1113 ; original value. At this point Carry set indicates FILE.
1114 ;
1115 RestoreReg <DI> ; get original SI
1116 JNC CheckDone ; if device then do not reset pointer
1117 MOV SI,DI
1118 CheckDone:
1119 RestoreReg <DI>
1120 CMC ; invert carry. Carry => device
1121 return
1122 else
1123 Procedure CheckThisDevice,NEAR
1124 DOSAssume CS,<ES>,"CheckThisDevice"
1125 ASSUME DS:NOTHING
1126 SaveReg <DI,SI>
1127 MOV DI,SI
1128 ;
1129 ; Check for presence of \dev\ (Dam multiplan!)
1130 ;
1131 MOV AL,[SI]
1132 Invoke PathChrCmp ; is it a path char?
1133 JNZ ParseDev ; no, go attempt to parse device
1134 INC SI ; simulate LODSB
1135 ;
1136 ; We have the leading path separator. Look for DEV part.
1137 ;
1138 LODSW
1139 OR AX,2020h
1140 CMP AX,"e" SHL 8 + "d"
1141 JNZ NotDevice ; not "de", assume not device
1142 LODSB
1143 OR AL,20h
1144 CMP AL,"v" ; Not "v", assume not device
1145 JNZ NotDevice
1146 LODSB
1147 invoke PathChrCmp ; do we have the last path separator?
1148 JNZ NotDevice ; no. go for it.
1149 ;
1150 ; DS:SI now points to a potential drive. Preserve them as NameTrans advances
1151 ; SI and DevName may destroy DS.
1152 ;
1153 ParseDev:
1154 SaveReg <DS,SI> ; preserve the source pointer
1155 invoke NameTrans ; advance DS:SI
1156 CMP BYTE PTR [SI],0 ; parse entire string?
1157 STC ; simulate a Carry return from DevName
1158 JNZ SkipSearch ; no parse. simulate a file return.
1159 Context DS
1160 Invoke DevName
1161 ASSUME DS:NOTHING
1162 SkipSearch:
1163 RestoreReg <SI,DS>
1164 ;
1165 ; SI points to the beginning of the potential device. If we have a device
1166 ; then we do not change SI. If we have a file, then we reset SI back to the
1167 ; original value. At this point Carry set indicates FILE.
1168 ;
1169 CheckReturn:
1170 RestoreReg <DI> ; get original SI
1171 JNC CheckDone ; if device then do not reset pointer
1172 MOV SI,DI
1173 CheckDone:
1174 RestoreReg <DI>
1175 CMC ; invert carry. Carry => device
1176 return
1177 NotDevice:
1178 STC
1179 JMP CheckReturn
1180 endif
1181
1182 EndProc CheckThisDevice
1183
1184 BREAK <LookupPath - call fastopen to get dir entry info>
1185
1186 ;
1187 ; Output DS:SI -> path name,
1188 ; ES:DI -> dir entry info buffer
1189 ; ES:CX -> extended dir info buffer
1190 ;
1191 ; carry flag clear : tables pointed by ES:DI and ES:CX are filled by
1192 ; FastOpen, DS:SI points to char just one after
1193 ; the last char of path name which is fully or
1194 ; partially found in FastOPen
1195 ; carry flag set : FastOpen not in memory or path name not found
1196 ;
1197 procedure LookupPath,NEAR
1198 ASSUME ES:NOTHING
1199
1200 ; PUSH AX
1201 TEST [FastOpenFlg],FastOpen_Set ; flg is set in DOSPEN
1202 JNZ FASTINST ; and this routine is
1203 NOLOOK:
1204 JMP NOLOOKUP ; executed once
1205 FASTINST:
1206 TEST [FastOpenFlg],No_Lookup ; no more lookup?
1207 JNZ NOLOOK ; yes
1208
1209 MOV BX,OFFSET DOSGROUP:FastOpenTable ; get fastopen related tab
1210 MOV SI,[Wfp_Start] ; si points to path name
1211 MOV DI,OFFSET DOSGROUP:Dir_Info_Buff
1212 MOV CX,OFFSET DOSGROUP:FastOpen_Ext_Info
1213 MOV AL,FONC_look_up ; al = 1
1214 PUSH DS
1215 POP ES
1216 CALL DWORD PTR [BX.FASTOPEN_NAME_CACHING] ;call fastopen
1217 JC NOTFOUND ; fastopen not in memory
1218
1219 LEA BX,[SI-2]
1220 CMP BX,[Wfp_Start] ; path found ?
1221 JZ NOTFOUND ; no
1222 ; fully or partially found
1223 CMP BYTE PTR [SI],0 ;AN000;FO.
1224 JNZ parfnd ;AN000;FO.; partiallyfound
1225 PUSH CX ;AN000;FO.; is attribute matched ?
1226 MOV CL,Attrib ;AN000;FO.;
1227 MOV CH,Sattrib ;AN000;FO.; attrib=sattrib
1228 MOV Attrib,CH ;AN000;FO.;
1229 MOV CH,ES:[DI.dir_attr] ;AN000;FO.;
1230 invoke Matchattributes ;AN000;FO.;
1231 ;;; MOV Attrib,CL ;AN001;FO.; retore attrib
1232 POP CX ;AN000;FO.;
1233 JNZ NOLOOKUP ;AN000;FO.; not matched
1234 parfnd:
1235 MOV [Next_Element_Start],SI ; save si
1236 MOV BX,CX
1237 MOV AX,[BX.FEI_lastent] ;AN000;;FO. restore lastentry
1238 MOV [LASTENT],AX ;AN000;;FO.
1239 MOV AX,[BX.FEI_dirstart] ;AN001;;FO. restore dirstart
1240 MOV [DIRSTART],AX ;AN001;;FO.
1241 MOV AX,[BX.FEI_clusnum] ; restore next cluster num
1242 MOV [CLUSNUM],AX ;
1243
1244 PUSH ES ; save ES
1245 LES BX,[THISDPB] ; put drive id
1246 MOV AH,ES:[BX.dpb_drive] ; in AH for DOOPEN
1247 POP ES ; pop ES
1248
1249 MOV WORD PTR [CURBUF+2],ES ; [curbuf+2].bx points to
1250 MOV BX,DI ; start of entry
1251 LEA SI,[DI.dir_first] ; [curbuf+2]:si points to
1252 ; dir_first field in the
1253 ; dir entry
1254 OR [FastOpenFlg],Lookup_Success + set_for_search
1255 ; POP AX
1256 RET
1257 NOTFOUND:
1258 CMP AX,-1 ; not in memory ?
1259 JNZ Partial_Success ; yes, in memory
1260 MOV [FastOpenFlg],0 ; no more fastopen
1261 Partial_Success:
1262 AND [FastOpenFlg],Special_Fill_Reset
1263 NOLOOKUP:
1264 ; POP AX
1265 STC
1266 RET
1267 EndProc LookupPath
1268
1269 BREAK <InsertPath - call fastopen to insert dir entry info>
1270
1271 ;
1272 ; Input: FastOpen_Set flag set when from DOSOPEN otherwise 0
1273 ; Lookup_Success flag set when got dir entry info from FASTOPEN
1274 ; DS = DOSGROUP
1275 ; Output: FastOPen_Ext_Info is set and path dir info is inserted
1276 ;
1277 procedure InsertPath,NEAR
1278 ASSUME ES:NOTHING
1279
1280 PUSHF
1281 TEST [FastOpenFlg],FastOpen_Set ;only DOSOPEN can take advantage of
1282 JZ GET_NEXT_ELEMENT ; the FastOpen
1283 TEST [FastOpenFlg],Lookup_Success ; Lookup just happened
1284 JZ INSERT_DIR_INFO ; no
1285 AND [FastOpenFlg],Lookup_Reset ; we got dir info from fastopen so
1286 MOV DI,[Next_Element_Start] ; no need to insert it again
1287 JMP GET_NEXT2
1288 INSERT_DIR_INFO: ; save registers
1289 PUSH DS
1290 PUSH ES
1291 PUSH BX
1292 PUSH SI
1293 PUSH DI
1294 PUSH CX
1295 PUSH AX
1296 ; int 3
1297 LDS DI,[CURBUF] ; DS:DI -> buffer header
1298 ASSUME DS:NOTHING
1299 MOV SI,OFFSET DOSGROUP:FastOpen_Ext_Info
1300 MOV AX,WORD PTR [DI.buf_sector] ; get directory sector
1301 MOV WORD PTR CS:[SI.FEI_dirsec],AX ;AN000; >32mb save dir sector
1302 MOV AX,WORD PTR [DI.buf_sector+2] ;AN000; >32mb
1303 context DS
1304 MOV WORD PTR [SI.FEI_dirsec+2],AX ;AN000;>32mb save high dir sector
1305 MOV AX,[CLUSNUM] ; save next cluster number
1306 MOV [SI.FEI_clusnum],AX
1307 MOV AX,[LASTENT] ;AN000;FO. save lastentry for search first
1308 MOV [SI.FEI_lastent],AX ;AN000;FO.
1309 MOV AX,[DIRSTART] ;AN001;FO. save for search first
1310 MOV [SI.FEI_dirstart],AX ;AN001;FO.
1311
1312 MOV AX,BX
1313 ADD DI,BUFINSIZ ; DS:DI -> start of data in buffer
1314 SUB AX,DI ; AX=BX relative to start of sector
1315 MOV CL,SIZE dir_entry
1316 ;invoke debug_DOS
1317 DIV CL
1318 MOV [SI.FEI_dirpos],AL ; save directory entry # in buffer
1319
1320 PUSH DS
1321 POP ES
1322
1323 MOV DS,WORD PTR [CURBUF+2]
1324 MOV DI,BX ; DS:DI -> dir entry info
1325 ASSUME DS:NOTHING
1326 CMP DS:[DI.dir_first],0 ; never insert info when file is empty
1327 JZ SKIP_INSERT ; e.g. newly created file
1328
1329 PUSH SI ; ES:BX -> extended info
1330 POP BX
1331
1332 MOV AL,FONC_insert ; call fastopen insert operation
1333 MOV SI,OFFSET DOSGROUP:FastOpenTable
1334 CALL DWORD PTR ES:[SI.FASTOPEN_NAME_CACHING]
1335
1336 CLC
1337 SKIP_INSERT:
1338 POP AX
1339 POP CX ; restore registers
1340 POP DI
1341 POP SI
1342 POP BX
1343 POP ES
1344 POP DS
1345 GET_NEXT2:
1346 OR [FastOpenFlg],No_Lookup ; we got dir info from fastopen so
1347 GET_NEXT_ELEMENT:
1348 POPF
1349 RET
1350 EndProc InsertPath
1351
1352 CODE ENDS
1353 END