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
5 ; Main Path cracking routines, low level search routines and device
6 ; name detection routines
22 ; A000 version 4.00 Jan. 1988
23 ; A001 PTM 3564 -- search using fastopen
26 ; get the appropriate segment definitions
31 CODE SEGMENT BYTE PUBLIC 'CODE'
32 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
37 include fastopen
.inc ;DOS 3.3
48 i_need CURR_DIR_END
,WORD
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
73 Break <GETPATH
-- PARSE A WFP
>
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
84 ; [THISDPB] set to DPB if disk otherwise garbage.
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]
93 ; Carry set if bad path
94 ; SI Points to path element causing failure
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
104 ; File in middle of path or bad name in path or attribute mismatch
105 ; or path too long or malformed path
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
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
129 procedure GETPATH
,near
130 DOSAssume
CS,<DS>,"GetPath"
133 MOV WORD PTR [CREATING
],0E500H ; Not Creating, not DEL *.*
135 ;Same as GetPath only CREATING and DELALL already set
137 MOV [EXTERR_LOCUS
],errLOC_Disk
138 MOV WORD PTR CurBuf
,-1 ; initial setting
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.
143 MOV DI,Wfp_Start
; point to the beginning of the name
144 CMP WORD PTR [DI+1],'\' SHL 8 + ':'
147 ; Let ChkDev find it in the device list
150 MOV SI,DI ; let CHKDEV see the original name
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.
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.
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.
171 mov si,offset DOSGroup:Name1
174 mov cx,8 ; 8 chars in device name
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
197 ; DX is the position of the last seen non-space + 1. We terminate the name
201 mov byte ptr [di],0 ; end of string
202 invoke Build_device_ent ; Clears carry sets zero
209 JMP InternalError ; freeze
212 ; Start off at the correct spot. Optimize if the current dir part is valid.
215 MOV SI,[CURR_DIR_END] ; get current directory pointer
217 JNZ LOOK_SING ; Yes, use it.
218 LEA SI,[DI+3] ; skip D:\
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
225 MOV BX,ES:[DI.curdir_ID]
226 MOV SI,[CURR_DIR_END]
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.
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
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
245 PUSH [SI-1] ; save \ and 1st char of next element
249 MOV BYTE PTR [SI-1],0 ; call fastopen to look up cur dir info
251 MOV BX,OFFSET DOSGROUP:FastOpenTable
252 MOV DI,OFFSET DOSGROUP:Dir_Info_Buff
253 MOV CX,OFFSET DOSGROUP:FastOpen_Ext_Info
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
262 jmp short GO_Chk_end ;Go to No_Curr_D
265 GO_Chk_end: ; restore registers
272 JNC GOT_SEARCH_CLUSTER ; crack based on cur dir
276 ; We must cract the path beginning at the root. Advance pointer to beginning
277 ; of path and go crack from root.
281 LEA SI,[SI+3] ; Skip "d:/"
282 LES BP,[THISDPB] ; Get ES:BP
285 ; We are able to crack from the current directory part. Go set up for search
286 ; of specified cluster.
289 LES BP,[THISDPB] ; Get ES:BP
301 ; Check to see if the name at DS:DI is a device. Returns carry set if not a
303 ; Blasts CX,SI,DI,AX,BX
305 Procedure ChkDev,NEAR
306 ASSUME ES:Nothing,DS:NOTHING
311 ASSUME ES:DOSGroup ; Now here is where ES is DOSGroup
313 MOV DI,OFFSET DOSGROUP:NAME1
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
350 Break <ROOTPATH, FINDPATH -- PARSE A PATH>
353 ; Same as FINDPATH but,
354 ; SI Points to asciz string of path which is assumed to start at
355 ; the root (no leading '/').
357 ; Search from root for path
359 ; Same as FINDPATH but:
360 ; If root directory specified, [CURBUF] and [NAME1] are NOT set, and
361 ; [NoSetDir] is ignored.
363 procedure ROOTPATH,near
365 DOSAssume CS,<DS>,"RootPath"
375 XOR AH,AH ; Sets "device ID" byte, sets zero
376 ; (dir), clears carry.
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 '/').
385 ; [DIRSEC] = Phys sec # of first sector of directory
386 ; [CLUSNUM] = Cluster # of next cluster
387 ; [CLUSFAC] = Sectors per cluster
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
397 ; ID1 field of [THISCDS] updated appropriately
398 ; [ATTRIB] = [SATTRIB]
399 ; ES:BP Points to DPB
401 ; Carry set if bad path
402 ; SI Points to path element causing failure
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
412 ; File in middle of path or bad name in path
413 ; or path too long or malformed path
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
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
437 DOSAssume CS,<DS>,"FindPath"
440 Assert ISDPB,<ES,BP>,"FindPath"
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
450 MOV ES:[DI.curdir_ID],CX ; Set current directory currency
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.
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.
465 MOV DI,OFFSET DOSGroup:Name1
473 MOV DI,OFFSET DOSGroup:Name1
474 XOR AH,AH ; bits for CL
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
490 INC CL ;AN000; KK incrment volid count
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
508 jmp short StoNam ;AN000;; 2/13/KK
509 Notkanjb: ;AN000;; 2/13/KK
523 MOV DI,OFFSET DOSGroup
:Name1
+8
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
549 POP DI ; Start of this element
550 POP ES ; Restore ES:BP
553 JMP BADPATH ; NUL parse (two delims most likely)
555 PUSH SI ; Start of next element
561 ; for last element of the path switch to the correct search attributes
568 ; check name1 to see if we have a device...
572 invoke DevName ; blast BX
573 POP ES ; Restore ES:BP
575 JC FindFile ; Not a device
576 OR AL,AL ; Test next char again
578 JMP FileInPath ; Device name in middle of path
581 POP SI ; Points to NUL at end of path
587 CMP BYTE PTR [NAME1],0E5H ; if 1st char = E5
589 MOV BYTE PTR [NAME1],05H ; change it to 05
593 PUSH DI ; Start of this element
595 PUSH CX ; CL return from NameTrans
596 ;DOS 3.3 FastOPen 6/12/86 F.C.
598 CALL LookupPath ; call fastopen to get dir entry
599 JNC DIR_FOUND ; found dir entry
601 ;DOS 3.3 FastOPen 6/12/86 F.C.
613 TEST BYTE PTR [BX+dir_attr],attr_directory
614 JNZ GO_NEXT ; DOS 3.3
615 JMP FileInPath ; Error or end of path
617 ; if we are not setting the directory, then check for end of string
620 CMP BYTE PTR [NoSetDir],0
622 MOV DX,DI ; Save pointer to entry
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
630 MOV DI,[Next_Element_Start] ; no need to insert it again
633 JNZ NEXT_ONE ; DOS 3.3
636 PUSH DI ; Put start of next element back on stack
638 MOV DS,CX ; Get back pointer to entry
642 MOV DX,[SI] ; Dir_first
644 ;DOS 3.3 FastOPen 6/12/86 F.C.
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)
654 POP AX ; restore device id (AH)
655 ADD SP,2 ; pop ds in stack
660 POP DS ; DS = [curbuf + 2]
661 ;DOS 3.3 FastOPen 6/12/86 F.C.
663 SUB BX,DI ; Offset into sector of start of entry
664 SUB SI,DI ; Offset into sector of dir_first
669 PUSH WORD PTR [DI.buf_sector] ;AN000;>32mb
670 PUSH WORD PTR [DI.buf_sector+2] ;AN000;>32mb
673 invoke SETDIRSRCH ; This uses UNPACK which might blow
674 ; the entry sector buffer
678 MOV [ALLOWED],allowed_RETRY + allowed_FAIL
680 invoke GETBUFFR ; Get the entry buffer back
687 POP DI ; Start of next element
688 MOV SI,DI ; Point with SI
692 invoke SET_BUF_AS_DIR
693 MOV DI,WORD PTR [CURBUF]
694 ADD SI,DI ; Get the offsets back
696 ; DOS 3.3 FasOpen 6/12/86 F.C.
700 POP DI ; Start of next element
701 CALL InsertPath ; insert dir entry info
703 ; DOS 3.3 FasOpen 6/12/86 F.C.
709 INC DI ; Skip over "/"
710 MOV SI,DI ; Point with SI
712 JNZ find_bad_name ; oops
713 JMP FINDPATH ; Next element
716 DEC SI ; Undo above INC to get failure point
722 POP DI ; Start of next element
723 context DS ; Got to from one place with DS gone
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
730 MOV DI,[Next_Element_Start] ; This takes care of one time lookup
739 MOV SI,DI ; Path too long
743 ; DOS 3.3 FasOpen 6/12/86 F.C.
745 CALL InsertPath ; insert dir entry info
747 ; DOS 3.3 FasOpen 6/12/86 F.C.
753 POP SI ; Start of next element
755 MOV SI,DI ; Start of bad element
756 OR AL,AL ; zero if bad element is last, non-zero if path too long
759 MOV Attrib,AL ; Make sure return correct
764 Break <STARTSRCH -- INITIATE DIRECTORY SEARCH>
769 ; Set up a search for GETENTRY and NEXTENTRY
771 ; ES:BP = Drive parameters
772 ; Sets up LASTENT, ENTFREE=ENTLAST=-1, VOLID=0
775 procedure StartSrch,NEAR
776 DOSAssume CS,<DS>,"StartSrch"
779 Assert ISDPB,<<WORD PTR THISDPB+2>,<WORD PTR THISDPB>>,"StartSrch"
783 MOV BYTE PTR [VOLID],AL ; No volume ID found
790 BREAK <MatchAttributes - the final check for attribute matching>
793 ; Input: [Attrib] = attribute to search for
794 ; CH = found attribute
797 ; Registers modified: noneski
798 procedure MatchAttributes,near
799 ASSUME DS:NOTHING,ES:NOTHING
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
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>
812 EndProc MatchAttributes
814 Break <DevName
- Look for name of device
>
819 ; ATTRIB set so that we can error out if looking for Volume IDs
821 ; Determine if file is in list of I/O drivers
823 ; Carry set if not a device
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
831 procedure DEVNAME
,NEAR
832 DOSAssume
CS,<ES,DS>,"DevName"
840 PUSH WORD PTR [NAME1
]
846 TEST Attrib
,attr_volume_id
; If looking for VOL id don't find devs
848 MOV SI,OFFSET DOSGROUP
:NULDEV
851 TEST [SI.SDEVATT
],DEVTYP
852 JZ SKIPDEV
; Skip block devices (NET and LOCAL)
855 MOV DI,OFFSET DOSGROUP
:NAME1
856 MOV CX,4 ; All devices are 8 letters
857 REPE CMPSW ; Check for name in list
861 LDS SI,DWORD PTR [SI] ; Get address of next device
862 CMP SI,-1 ; At end of list?
864 RET31: STC ; Not found
877 MOV WORD PTR [DEVPT
+2],DS ; Save pointer to device
878 MOV BH,BYTE PTR [SI.SDEVATT
]
880 AND BH,NOT 020H ; Clears Carry
881 MOV WORD PTR [DEVPT
],SI
885 BREAK <Build_device_ent
- Make a Directory
entry>
889 ; BH is attribute field (supplied by DEVNAME)
890 ; [DEVPT] points to device header (supplied by DEVNAME)
892 ; Build a directory entry for a device at DEVFCB
894 ; BX points to DEVFCB
895 ; SI points to dir_first field
899 ; Zero Set, Carry Clear
900 ; DS,ES,BP preserved, others destroyed
902 procedure Build_device_ent
,near
903 DOSAssume
CS,<ES,DS>,"Build_Device_Ent"
906 MOV DI,OFFSET DOSGROUP
:DEVFCB
+8 ; Point to extent field
911 STOSB ; Blank out extent field
916 STOSB ; Set attribute field
922 REP STOSW ; Fill rest with zeros
924 MOV DI,OFFSET DOSGROUP
:DEVFCB
+dir_time
935 MOV SI,DI ; SI points to dir_first field
936 MOV AX,WORD PTR [DEVPT
]
940 STOSW ; Dir_first points to device
941 MOV AX,WORD PTR [DEVPT
+2]
946 MOV AH,BH ; Put device atts in AH
947 MOV BX,OFFSET DOSGROUP
:DEVFCB
948 XOR AL,AL ; Set zero, clear carry
950 EndProc Build_device_ent
952 Break <ValidateCDS
- given a CDS
, validate the media
and the current directory
>
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.
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
965 ; Carry set if error (currently user FAILed to I 24)
966 ; Registers modified: all
968 Procedure ValidateCDS
,NEAR
969 ASSUME
CS:DOSGroup
,DS:NOTHING
,ES:NOTHING
,SS:DOSGroup
970 Public DIR2001S
,DIR2001E
973 LocalVar SaveCDS
,DWORD
981 TEST [SI].curdir_flags
,curdir_isnet
; Clears carry
993 Context
DS ; FatReadCDS (ThisCDS);
1000 LDS SI,ThisCDS
; if (ThisCDS->ID == -1) {
1002 CMP [SI].curdir_ID
,-1
1005 SaveReg
<wfp_Start
> ; t = wfp_Start;
1006 CMP SI,SaveCDSL
; if not spliced
1009 MOV wfp_Start
,DI ; wfp_start = d;
1010 Invoke FStrCpy
; strcpy (d, ThisCDS->Text);
1013 SaveReg
<<WORD PTR SAttrib
>,BP> ; c = DOSChDir ();
1015 RestoreReg
<BP,BX,wfp_start
> ; wfp_Start = t;
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;
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.
1031 MOV [SI].curdir_ID
,CX ; }
1034 MOV WORD PTR ThisCDS
,DI
1035 MOV WORD PTR ThisCDS
+2,ES
1044 Break <CheckThisDevice
- Check for being a device
>
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:
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.
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
1066 Procedure CheckThisDevice
,NEAR
1067 DOSAssume
CS,<ES>,"CheckThisDevice"
1071 ; Advance to after the final path character.
1073 MOV DI,SI ; remember first character
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.
1087 ;kanji load of next char too 2/13/KK
1089 kanji
load of next char too
1091 invoke PathChrCmp
; is it a path char?
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.
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.
1115 RestoreReg
<DI> ; get original SI
1116 JNC CheckDone
; if device then do not reset pointer
1120 CMC ; invert carry. Carry => device
1123 Procedure CheckThisDevice
,NEAR
1124 DOSAssume
CS,<ES>,"CheckThisDevice"
1129 ; Check for presence of \dev\ (Dam multiplan!)
1132 Invoke PathChrCmp
; is it a path char?
1133 JNZ ParseDev
; no, go attempt to parse device
1134 INC SI ; simulate LODSB
1136 ; We have the leading path separator. Look for DEV part.
1140 CMP AX,"e" SHL 8 + "d"
1141 JNZ NotDevice
; not "de", assume not device
1144 CMP AL,"v" ; Not "v", assume not device
1147 invoke PathChrCmp
; do we have the last path separator?
1148 JNZ NotDevice
; no. go for it.
1150 ; DS:SI now points to a potential drive. Preserve them as NameTrans advances
1151 ; SI and DevName may destroy DS.
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.
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.
1170 RestoreReg
<DI> ; get original SI
1171 JNC CheckDone
; if device then do not reset pointer
1175 CMC ; invert carry. Carry => device
1182 EndProc CheckThisDevice
1184 BREAK <LookupPath
- call fastopen to get dir
entry info
>
1187 ; Output DS:SI -> path name,
1188 ; ES:DI -> dir entry info buffer
1189 ; ES:CX -> extended dir info buffer
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
1197 procedure LookupPath
,NEAR
1201 TEST [FastOpenFlg
],FastOpen_Set
; flg is set in DOSPEN
1202 JNZ FASTINST
; and this routine is
1204 JMP NOLOOKUP
; executed once
1206 TEST [FastOpenFlg
],No_Lookup
; no more lookup?
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
1216 CALL DWORD PTR [BX.FASTOPEN_NAME_CACHING
] ;call fastopen
1217 JC NOTFOUND
; fastopen not in memory
1220 CMP BX,[Wfp_Start
] ; path found ?
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
1233 JNZ NOLOOKUP
;AN000;FO.; not matched
1235 MOV [Next_Element_Start
],SI ; save si
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
1245 LES BX,[THISDPB
] ; put drive id
1246 MOV AH,ES:[BX.dpb_drive
] ; in AH for DOOPEN
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
1254 OR [FastOpenFlg
],Lookup_Success
+ set_for_search
1258 CMP AX,-1 ; not in memory ?
1259 JNZ Partial_Success
; yes, in memory
1260 MOV [FastOpenFlg
],0 ; no more fastopen
1262 AND [FastOpenFlg
],Special_Fill_Reset
1269 BREAK <InsertPath
- call fastopen to insert dir
entry info
>
1272 ; Input: FastOpen_Set flag set when from DOSOPEN otherwise 0
1273 ; Lookup_Success flag set when got dir entry info from FASTOPEN
1275 ; Output: FastOPen_Ext_Info is set and path dir info is inserted
1277 procedure InsertPath
,NEAR
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
1288 INSERT_DIR_INFO: ; save registers
1297 LDS DI,[CURBUF
] ; DS:DI -> buffer header
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
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.
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
1318 MOV [SI.FEI_dirpos
],AL ; save directory entry # in buffer
1323 MOV DS,WORD PTR [CURBUF
+2]
1324 MOV DI,BX ; DS:DI -> dir entry info
1326 CMP DS:[DI.dir_first
],0 ; never insert info when file is empty
1327 JZ SKIP_INSERT
; e.g. newly created file
1329 PUSH SI ; ES:BX -> extended info
1332 MOV AL,FONC_insert
; call fastopen insert operation
1333 MOV SI,OFFSET DOSGROUP
:FastOpenTable
1334 CALL DWORD PTR ES:[SI.FASTOPEN_NAME_CACHING
]
1339 POP CX ; restore registers
1346 OR [FastOpenFlg
],No_Lookup
; we got dir info from fastopen so