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