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
|
PAGE ,132 ; ;AN000;
; SCCSID = @(#)ifshand.asm 1.0 87/05/11 ;AN000;
TITLE IFSFUNC HANDLE ROUTINES - Routines for FS dispatch ;AN000;
NAME IFSHANDLE ;AN000;
;******************************************************************************
;
; HANDLE (SFT) related FS calls
;
;
; IFS_CLOSE
; IFS_COMMIT
; IFS_LSEEK
; IFS_READ
; IFS_WRITE
; IFS_LOCK
; IFS_XATTR
;
; REVISION HISTORY:
; A000 Original version 4.00 May 1987
; A001 P635 - Correct Read problem - restore es:di -> sft
; RG Sept 1,1987
; A002 P659 - Copy cmd problems (xattr)
; RG Sept 1,1987
; A003 P868 - Lock problems R.G
; A004 P849 - Printer problems R.G
; A005 P1601- lock/xattr problems R.G
; A006 P????- Write Only Lock support in Lock Read/Write 10/27 FEIGENBAUM
; A007 P2339- Not getting count back to user in xattr call 11/09 RG
; A008 P2433- redir copy problem (Xattr) 11/17 RG
; A009 P2566- xattrs not propagated across network 12/3 RG
; (due to size check on set that does not offer size)
; A010 D285 - Remove Extended Attributes/Lock 1/88 RG
; A011 P2994- double close problem 1/88 RG
; A012 P3149- basica file redirection - seek problem 1/88 RMG
; A013 P3185- get ea cx check 1/88 RMG
; A014 P3249- lock problem 1/88 RMG
; A015 P3432- copy to remote ptr problem - write 2/88 RMG
; A016 P3513- return cx on xattr wrong 2/88 RMG
; A017 P3968- set sf time/date on close 3/25/88 RMG
; A018 P4839- fcb open/ren/term problem on abort close 5/13/88 RMG
; A019 P4791- don't overwrite ax on error 5/19/88 RMG
; A020 P5003- LSEEK hang using Austin Test tool 6/01/88 RPS
;
; LOC - 251
; Programming note: In the prologues to the routines, the input/output are
; accurate. The pseudocode, however, is outdated and does
; not reflect the code.
;
;******************************************************************************
;AN000;
.xlist ;AN000;
.xcref ;AN000;
INCLUDE IFSSYM.INC ;AN000;
INCLUDE IFSFSYM.INC ;AN000;
INCLUDE DOSSYM.INC ;AN000;
INCLUDE DEVSYM.INC ;AN000;
;AN000;
.cref ;AN000;
.list ;AN000;
;AN000;
AsmVars <IBM, Installed, DEBUG> ;AN000;
;AN000;
; define the base code segment of the network support first ;AN000;
;AN000;
IFSSEG SEGMENT BYTE PUBLIC 'IFSSEG' ;AN000;
IFSSEG ENDS ;AN000;
;AN000;
; include THE REST of the segment definitions for normal MSDOS ;AN000;
;AN000;
include dosseg.asm ;AN000;
;AN000;
DATA SEGMENT WORD PUBLIC 'DATA' ;AN000;
;DOSGROUP Data ;AN000;
Extrn THISSFT:DWORD ;AN000;
Extrn DMAADD:DWORD ;AN000;
Extrn CurrentPDB:WORD ;AN000;
Extrn SAVE_BX:WORD
Extrn SAVE_CX:WORD
Extrn SAVE_DS:WORD
Extrn SAVE_SI:WORD
Extrn SAVE_ES:WORD
Extrn SAVE_DI:WORD
DATA ENDS ;AN000;
;AN000;
;AN000;
; define our own code segment ;AN000;
;AN000;
IFSSEG SEGMENT BYTE PUBLIC 'IFSSEG' ;AN000;
ASSUME SS:DOSGROUP,CS:IFSSEG ;AN000;
;AN000;
;IFS Data ;AN000;
Extrn THISDFL:DWORD ;AN000;
Extrn THISIFS:DWORD ;AN000;
Extrn IFSPROC_FLAGS:WORD ;AN000;
Extrn IFSR:WORD ;AN000;
Extrn DEVICE_CB@_OFFSET:WORD ;AN000;
;AN000;
BREAK <IFS_CLOSE Close a FS SFT> ;AN000;
;AN000;
;****************************************************************************** ;AN000;
; ;AN000;
; IFS_CLOSE - see IFS_COMMIT for details ;AN000;
; ;AN000;
;****************************************************************************** ;AN000;
;AN000;
procedure IFS_CLOSE,NEAR ;AN000;
ASSUME DS:DOSGROUP,ES:NOTHING ;AN000;
;AN000;
ifsr_fcn_def EXECAPI ; define ifsr for close ;AN000;
ifsr_api_def CLOSEFILE ;AN000;
;AN000;
TEST ES:[DI.SF_FLAGS],devid_file_clean + sf_close_nodate ;AN017;
JNZ C_05 ;AN017;
CallInstall DATE16,MultDOS,13 ; set sf date/time on close ;AN017;
MOV ES:[DI.SF_DATE],AX ;AN017;
MOV ES:[DI.SF_TIME],DX ;AN017;
C_05: ;AN017;
SaveReg <ES,DI> ; save SFT ptr ;AN000;
CallInstall FREE_SFT,MultDOS,8 ; set SFT busy ;AN000;
PUSH AX ; save old ref count ;AN000;
;AN000;
TEST ES:[DI.SF_MODE],SF_ISFCB ; always close fcb ;AN011;
JNZ C_10 ; only do real close when ;AN011;
CMP AX,1 ; sft being freed ;AN011;
JE C_10 ;AN011;
JMP C_80 ;AN011;
C_10: ;AN011;
MOV CS:IFSPROC_FLAGS,ISCLOSE + SETDEVICECB ;AN000;
; 2nd flag causes sft_to_sff to ;AN000;
; set device cb@ ;AN000;
JMP C_20 ; cont. in ifs_commit ;AN000;
;AN000;
EndProc IFS_CLOSE ;AN000;
;AN000;
BREAK <IFS_COMMIT Commit a FS SFT> ;AN000;
;AN000;
;****************************************************************************** ;AN000;
; ;AN000;
; IFS_COMMIT ;AN000;
; ;AN000;
; Called by: IFSFUNC dispatcher ;AN000;
; ;AN000;
; Routines called: CALL_IFS DRIVE_FROM_SFT ;AN000;
; SFT_TO_SFF ;AN000;
; SFF_TO_SFT ;AN000;
; ;AN000;
; Inputs: ;AN000;
; [THISSFT] set to the SFT for the file being used ;AN000;
; ES:DI = [THISSFT] (date time are NOT correct) ;AN000;
; SFT must never be for an FCB on commit (error not detected) ;AN000;
; ;AN000;
; Function: ;AN000;
; Prep IFSRH: ;AN000;
; * IFSR_LENGTH DW 40 ; Total length of request ;AN000;
; * IFSR_FUNCTION DB 4 ; Execute API function ;AN000;
; + IFSR_RETCODE DW ? ;AN000;
; + IFSR_RETCLASS DB ? ;AN000;
; IFSR_RESV1 DB 16 DUP(0) ;AN000;
; * IFSR_APIFUNC DB 14 ; Close/commit file ;AN000;
; + IFSR_ERROR_CLASS DB ? ;AN000;
; + IFSR_ERROR_ACTION DB ? ;AN000;
; + IFSR_ERROR_LOCUS DB ? ;AN000;
; + IFSR_ALLOWED DB ? ;AN000;
; + IFSR_I24_RETRY DB ? ;AN000;
; + IFSR_I24_RESP DB ? ;AN000;
; IFSR_RESV2 DB ? ;AN000;
; *+ IFSR_DEVICE_CB@ DD ? ;AN000;
; *+ IFSR_OPEN_CB@ DD ? ; SF ;AN000;
; * IFSR_FUNC DB ? ; 0=CLOSE, 1=COMMIT ;AN000;
; IFSR_RESV2 DB 0 ;AN000;
; ;AN000;
; IF close THEN ;AN000;
; IFSR_FUNC = 0 ;AN000;
; ELSE IFSR_FUNC = 1 ;AN000;
; CALL routine, CALL_IFS, with pointer to SF_IFS_HDR ;AN000;
; IF IFSR_RETCODE = 0 THEN ;AN000;
; DO ;AN000;
; Call SFF_TO_SFT ;AN000;
; Decrement SF_REF_COUNT if close ;AN000;
; Clear carry ;AN000;
; ENDDO ;AN000;
; ELSE DO {error} ;AN000;
; AX = IFSR_RETCODE ;AN000;
; Set carry ;AN000;
; ENDDO ;AN000;
; ENDIF ;AN000;
; ;AN000;
; Outputs: ;AN000;
; sf_ref_count decremented on close unless FAIL ;AN000;
; (AX has old value for COMMIT) ;AN000;
; ES:DI point to SFT ;AN000;
; Carry set if error (file deleted or disk changed) ;AN000;
; ;AN000;
; DS preserved, others destroyed ;AN000;
; ;AN000;
;****************************************************************************** ;AN000;
;AN000;
procedure IFS_COMMIT,NEAR ;AN000;
ASSUME DS:DOSGROUP,ES:NOTHING ;AN000;
;AN000;
ifsr_fcn_def EXECAPI ;AN000;
ifsr_api_def CLOSEFILE ;AN000;
;AN000;
MOV CS:IFSPROC_FLAGS,SETDEVICECB ; set ifsproc_flags ;AN000;
C_20: ; (welcome ifs_close) ;AN000;
invoke DRIVE_FROM_SFT ; set IFSDRV for possible criter ;AN000;
invoke PREP_IFSR ; clear ifsrh ;AN000;
MOV DEVICE_CB@_OFFSET,IFSR_DEVICE_CB@ ;AN000;
invoke SFT_TO_SFF ; sets: [THISIFS] ;AN000;
; ES:BX -> IFSRH ;AN000;
; IFSR_OPEN_CB@ ;AN000;
; ds - IFSSEG ;AN000;
;AN000;
MOV ES:[BX.IFSR_LENGTH],LENGTH_CLOSEFILE ; prep IFSRH ;AN000;
MOV ES:[BX.IFSR_FUNCTION],IFSEXECAPI ;AN000;
MOV ES:[BX.IFSR_APIFUNC],IFSCLOSEFILE ;AN000;
XOR AL,AL ;AN000;
TEST IFSPROC_FLAGS,ISCLOSE ;AN000;
JNZ C_40 ;AN000;
INC AL ;AN000;
C_40: ;AN000;
MOV ES:[BX.IFSR_FUNC],AL ;AN000;
;AN000;
invoke CALL_IFS ; *** call fs with close request ;AN000;
;AN000;
JNC C_60 ;AN000;
TEST IFSPROC_FLAGS,ISCLOSE ; ifs error ;AN000;
JZ C_980 ; return w/carry, if close ;AN000;
;;;;;;;;ADD SP,6 ; restore stack first ;AD018;
RestoreReg <CX,DI,ES> ; old ref count & sft ;AN018;;AC019;
CMP CX,1 ;AN018;;AC019;
JNE C_980 ;AN018;
MOV ES:[DI.sf_ref_count],0 ; If freeing, need to zap ;AN018;
JMP C_980 ;AN000;
C_60: ;AN000;
invoke SFF_TO_SFT ;AN000;
TEST IFSPROC_FLAGS,ISCLOSE ;AN000;
JZ C_990 ; finished w/commit ;AN000;
C_80: ;AN011;
RestoreReg <AX,DI,ES> ; old ref count & sft ;AN000;
CMP AX,1 ;AN000;
JNE C_990 ;AN000;
MOV ES:[DI.sf_ref_count],0 ; If freeing, need to zap ;AN000;
JMP C_990 ; busy mark ;AN000;
;AN000;
;AN000;
C_980: ; Return area ;AN000;
STC ;AN000;
JMP C_1000 ;AN000;
C_990: ;AN000;
CLC ;AN000;
C_1000: ; preserve ds - dosgroup ;AN000;
PUSH SS ;AN000;
POP DS ;AN000;
return ;AN000;
;AN000;
EndProc IFS_COMMIT ;AN000;
;AN000;
BREAK <IFS_LSEEK Seek on a NET SFT> ;AN000;
;AN000;
;****************************************************************************** ;AN000;
; ;AN000;
; IFS_LSEEK ;AN000;
; ;AN000;
; Inputs: ;AN000;
; ES:DI -> SFT ;AN000;
; CX:DX = Input CX:DX to $Lseek (offset) ;AN000;
; NOTE: THIS LSEEK IS ALWAYS ASSUMED TO BE A TYPE 2 (relative to EOF) ;AN000;
; Function: ;AN000;
; Prep IFSRH: ;AN000;
; * IFSR_LENGTH DW 44 ; Request length ;AN000;
; * IFSR_FUNCTION DB 4 ; Execute API function ;AN000;
; + IFSR_RETCODE DW ? ;AN000;
; + IFSR_RETCLASS DB ? ;AN000;
; IFSR_RESV1 DB 16 DUP(0) ;AN000;
; * IFSR_APIFUNC DB 10 ; Lseek file ;AN000;
; + IFSR_ERROR_CLASS DB ? ;AN000;
; + IFSR_ERROR_ACTION DB ? ;AN000;
; + IFSR_ERROR_LOCUS DB ? ;AN000;
; + IFSR_ALLOWED DB ? ;AN000;
; + IFSR_I24_RETRY DB ? ;AN000;
; + IFSR_I24_RESP DB ? ;AN000;
; IFSR_RESV2 DB ? ;AN000;
; IFSR_DEVICE_CB@ DD ? ;AN000;
; *+ IFSR_OPEN_CB@ DD ? ; Call SFT_TO_SFFto convert SFT to SF ;AN000;
; ; and set this as pointer to it. ;AN000;
; * IFSR_MODE DB 2 ; Position mode: - BL ;AN000;
; ; 2 = ptr moved eof + offset ;AN000;
; IFSR_RESV2 DB 0 ;AN000;
; * IFSR_POSITION DD ? ; displacement of LSEEK - CX:DX ;AN000;
; ;AN000;
; CALL routine, CALL_IFS, with pointer to SF_IFSR_HDR ;AN000;
; IF IFSR_RETCODE = 0 THEN ;AN000;
; DO ;AN000;
; Call SFF_TO_SFT ;AN000;
; Set DX:AX = IFSR_POSITION ;AN000;
; Clear carry ;AN000;
; ENDDO ;AN000;
; ELSE DO {error} ;AN000;
; AX = IFSR_RETCODE ;AN000;
; Set carry ;AN000;
; ENDDO ;AN000;
; ENDIF ;AN000;
; Returns: ;AN000;
; ES:DI -> SFT ;AN000;
; Carry clear ;AN000;
; DX:AX return as with local $Lseek ;AN000;
; Carry Set ;AN000;
; AX is error code ;AN000;
; All destroyed ;AN000;
; ;AN000;
;****************************************************************************** ;AN000;
;AN000;
procedure IFS_LSEEK,NEAR ;AN000;
ASSUME DS:Nothing,ES:NOTHING ; Initially DS is unknown ;AN020;
;AN000;
ifsr_fcn_def EXECAPI ; define ifsr for lseek ;AN000;
ifsr_api_def LSEEKFILE ;AN000;
;AN000;
PUSH SS ; Set DS to DOSGROUP ;AN020;
POP DS ; ;AN020;
ASSUME DS:DOSGROUP ; ;AN020;
MOV CS:IFSPROC_FLAGS,SETDEVICECB ; init processing flags ;AN000;
MOV WORD PTR [THISSFT],DI ;AN020;
MOV WORD PTR [THISSFT+2],ES ;AN020;
SaveReg <ES,DI> ; save for later restore before leave ;AN012;;AN020;
invoke PREP_IFSR ;AN000;
;AN000;
invoke DRIVE_FROM_SFT ; set IFSDRV for possible criter ;AN000;
MOV CS:DEVICE_CB@_OFFSET,IFSR_DEVICE_CB@ ;AN000;
invoke SFT_TO_SFF ; sets: [THISIFS] ;AN000;
; ES:BX -> IFSRH ;AN000;
; IFSR_OPEN_CB@ ;AN000;
; ds - IFSSEG ;AN000;
;AN000;
MOV ES:[BX.IFSR_LENGTH],LENGTH_LSEEKFILE ; prep IFSRH ;AN000;
MOV ES:[BX.IFSR_FUNCTION],IFSEXECAPI ;AN000;
MOV ES:[BX.IFSR_APIFUNC],IFSLSEEKFILE ;AN000;
MOV ES:[BX.IFSR_MODE],MODE2 ;AN000;
MOV WORD PTR ES:[BX.IFSR_POSITION],DX ;AN000;
MOV WORD PTR ES:[BX.IFSR_POSITION+2],CX ;AN000;
;AN000;
invoke CALL_IFS ; call fs with lseek request ;AN000;
;AN000;
JC LS_1000 ;AN000;
MOV AX,WORD PTR ES:[BX.IFSR_POSITION] ;AN000;
MOV DX,WORD PTR ES:[BX.IFSR_POSITION+2] ;AN000;
invoke SFF_TO_SFT ;AN000;
;AN000;
CLC ;AN000;
LS_1000: ;AN000;
RestoreReg <DI,ES> ; restore sft ptr for ibmdos ;AN012;
return ;AN000;
;AN000;
EndProc IFS_LSEEK ;AN000;
;AN000;
BREAK <IFS_READ Read from a NET SFT> ;AN000;
;AN000;
;****************************************************************************** ;AN000;
; ;AN000;
; IFS_READ ;AN000;
; ;AN000;
; Called by: IFSFUNC dispatcher ;AN000;
; ;AN000;
; Routines called: CALL_IFS ;AN000;
; SFT_TO_SFF ;AN000;
; SFF_TO_SFT ;AN000;
; ;AN000;
; Inputs: ;AN000;
; Outputs of SETUP: ;AN000;
; CX = byte count ;AN000;
; ES:DI Points to SFT ;AN000;
; [DMAADD] = transfer addr ;AN000;
; SFT checked for access mode ;AN000;
; Function: ;AN000;
; Prep IFSRH: ;AN000;
; * IFSR_LENGTH DW 46 ; Total length of request ;AN000;
; * IFSR_FUNCTION DB 4 ; Execute API function ;AN000;
; + IFSR_RETCODE DW ? ;AN000;
; + IFSR_RETCLASS DB ? ;AN000;
; IFSR_RESV1 DB 16 DUP(0) ;AN000;
; * IFSR_APIFUNC DB 11 ; Read Byte Block ;AN000;
; + IFSR_ERROR_CLASS DB ? ;AN000;
; + IFSR_ERROR_ACTION DB ? ;AN000;
; + IFSR_ERROR_LOCUS DB ? ;AN000;
; + IFSR_ALLOWED DB ? ;AN000;
; + IFSR_I24_RETRY DB ? ;AN000;
; + IFSR_I24_RESP DB ? ;AN000;
; IFSR_RESV2 DB ? ;AN000;
; *+ IFSR_DEVICE_CB@ DD ? ; CD/DF - specified in SF_DEVPTR ;AN000;
; *+ IFSR_OPEN_CB@ DD ? ; Call SFT_TO_SFFto convert SFT to SF ;AN000;
; ; and set this as pointer to it. ;AN000;
; IFSR_RESV3 DW 0 ;AN000;
; IFSR_COUNT DW 0 ;AN000;
; *+ IFSR_BUFFER@ DD ? ; [DMAADD] ;AN000;
; ;AN000;
; CALL routine, CALL_IFS, with pointer to SF_IFSR_HDR ;AN000;
; IF IFSR_RETCODE = 0 THEN ;AN000;
; DO ;AN000;
; Call SFF_TO_SFT ;AN000;
; CX = IFSR_COUNT ;AN000;
; ES:DI -> SFT ;AN000;
; ENDDO ;AN000;
; ELSE DO {error} ;AN000;
; AX = IFSR_RETCODE ;AN000;
; CX = 0 ;AN000;
; ES:DI -> SFT ;AN000;
; Set carry ;AN000;
; ENDDO ;AN000;
; ENDIF ;AN000;
; Outputs: ;AN000;
; Carry clear ;AN000;
; SFT Position updated ;AN000;
; CX = No. of bytes read ;AN000;
; ES:DI point to SFT ;AN000;
; [DMAADD] filled with info read ;AN000;
; Carry set ;AN000;
; AX is error code ;AN000;
; CX = 0 ;AN000;
; ES:DI point to SFT ;AN000;
; DS preserved, all other registers destroyed ;AN000;
; ;AN000;
;****************************************************************************** ;AN000;
;AN000;
procedure IFS_READ,NEAR ;AN000;
ASSUME DS:DOSGROUP,ES:NOTHING ;AN000;
;AN000;
ifsr_fcn_def EXECAPI ; define ifsr for read ;AN000;
MOV CS:IFSPROC_FLAGS,SetDeviceCB ;AN000;
MOV WORD PTR [THISSFT],DI ; set thissft ;AN000;
MOV WORD PTR [THISSFT+2],ES ;AN000;
;AN000;
R_20: ; (welcome lock/read) ;AN000;
ifsr_api_def READFILE ;AN000;
invoke PREP_IFSR ; zero out ifsr, es:bx -> ifsr ;AN000;
MOV ES:[BX.IFSR_LENGTH],LENGTH_READFILE ; prep IFSRH ;AN000;
MOV ES:[BX.IFSR_APIFUNC],IFSREADFILE ;AN000;
; XOR AL,AL ; for now, set mode = read (0) ;AD010;
; TEST CS:IFSPROC_FLAGS,ISLOCKREAD ;AD010;
; JZ W_80 ;AD010;
; INC AL ; inc mode to mode_lock_read ;AD010;
JMP W_80 ; cont. read/write common code ;AN000;
; in ifs_write below ;AN000;
;AN000;
EndProc IFS_READ ;AN000;
;AN000;
BREAK <IFS_WRITE Write to a NET SFT> ;AN000;
;AN000;
;****************************************************************************** ;AN000;
; ;AN000;
; IFS_WRITE ;AN000;
; ;AN000;
; Called by: IFSFUNC dispatcher ;AN000;
; ;AN000;
; Routines called: CALL_IFS ;AN000;
; SFT_TO_SFF ;AN000;
; SFF_TO_SFT ;AN000;
; ;AN000;
; Inputs: ;AN000;
; Outputs of SETUP: ;AN000;
; CX = byte count ;AN000;
; ES:DI Points to SFT ;AN000;
; [DMAADD] = transfer addr ;AN000;
; SFT checked for access mode ;AN000;
; Function: ;AN000;
; Prep IFSRH: ;AN000;
; * IFSR_LENGTH DW 46 ; Length of request ;AN000;
; * IFSR_FUNCTION DB 4 ; Execute API function ;AN000;
; + IFSR_RETCODE DW ? ;AN000;
; + IFSR_RETCLASS DB ? ;AN000;
; IFSR_RESV1 DB 16 DUP(0) ;AN000;
; * IFSR_APIFUNC DB 12 ; Write Byte Block ;AN000;
; + IFSR_ERROR_CLASS DB ? ;AN000;
; + IFSR_ERROR_ACTION DB ? ;AN000;
; + IFSR_ERROR_LOCUS DB ? ;AN000;
; + IFSR_ALLOWED DB ? ;AN000;
; + IFSR_I24_RETRY DB ? ;AN000;
; + IFSR_I24_RESP DB ? ;AN000;
; IFSR_RESV2 DB ? ;AN000;
; *+ IFSR_DEVICE_CB@ DD ? ;AN000;
; *+ IFSR_OPEN_CB@ DD ? ; call SFT_TO_SFF & set this as ptr ;AN000;
; IFSR_RESV3 DW 0 ;AN000;
; * IFSR_COUNT DW ? ; # bytes to write - CX ;AN000;
; * IFSR_BUFFER@ DD ? ; Data buffer - [DMAADD] ;AN000;
; ;AN000;
; CALL routine, CALL_IFS, with pointer to SF_IFSR_HDR ;AN000;
; IF IFSR_RETCODE = 0 THEN ;AN000;
; DO ;AN000;
; Call SFF_TO_SFT ;AN000;
; CX = IFSR_COUNT ;AN000;
; ES:DI -> SFT ;AN000;
; Clear carry ;AN000;
; ENDDO ;AN000;
; ELSE DO {error} ;AN000;
; AX = IFSR_RETCODE ;AN000;
; CX = 0 ;AN000;
; ES:DI -> SFT ;AN000;
; Set carry ;AN000;
; ENDDO ;AN000;
; ENDIF ;AN000;
; Outputs: ;AN000;
; Carry clear ;AN000;
; SFT Position updated ;AN000;
; CX = No. of bytes written ;AN000;
; ES:DI point to SFT ;AN000;
; Carry set ;AN000;
; AX is error code ;AN000;
; CX = 0 ;AN000;
; ES:DI point to SFT ;AN000;
; DS preserved, all other registers destroyed ;AN000;
; ;AN000;
;****************************************************************************** ;AN000;
;AN000;
procedure IFS_WRITE,NEAR ;AN000;
ASSUME DS:DOSGROUP,ES:NOTHING ;AN000;
;AN000;
ifsr_fcn_def EXECAPI ; define ifsr for write ;AN000;
MOV CS:IFSPROC_FLAGS,SetDeviceCB ; init processing flags ;AN000;
MOV WORD PTR [THISSFT],DI ; set thissft ;AN000;
MOV WORD PTR [THISSFT+2],ES ;AN000;
;AN000;
W_20: ; (welcome write/unlock) ;AN000;
ifsr_api_def WRITEFILE ;AN000;
invoke PREP_IFSR ;AN000;
MOV ES:[BX.IFSR_LENGTH],LENGTH_WRITEFILE ; prep IFSRH ;AN000;
MOV ES:[BX.IFSR_APIFUNC],IFSWRITEFILE ;AN000;
; XOR AL,AL ; for now set mode to write (bit0=0) ;AD010;
; TEST CS:IFSPROC_FLAGS,ISWRITEUNLOCK ;AD010;
; JZ W_40 ;AD010;
; INC AL ; set mode to write/unlock (bit0=1) ;AD010;
;W_40: ;AD010;
; TEST CS:IFSPROC_FLAGS,ISADD ;AD010;
; JZ W_80 ;AD010;
; OR AL,MODE_ADD_MASK ; set mode to add (bit 1) ;AD010;
;W_80: ; (welcome read) ;AD010;
; TEST CS:IFSPROC_FLAGS,ISWOLOCK ;AD010; BAF
; JZ W_90 ;AD010; BAF
; OR AL,MODE_WO_MASK ; set mode to Write Only Lock ;AD010; BAF
;W_90: ;AD010; BAF
; MOV ES:[BX.IFSR_MODE],AL ;AD010;
W_80: ; (welcome read) ;AN010;
MOV CS:DEVICE_CB@_OFFSET,IFSR_DEVICE_CB@ ;AC015;
MOV ES:[BX.IFSR_FUNCTION],IFSEXECAPI ;AN000;
MOV ES:[BX.IFSR_COUNT],CX ;AN000;
;AN000;
MOV AX,WORD PTR [DMAADD] ; to access dmaadd ;AN000;
MOV WORD PTR ES:[BX.IFSR_BUFFER@],AX ;AN000;
MOV AX,WORD PTR [DMAADD+2] ;AN000;
MOV WORD PTR ES:[BX.IFSR_BUFFER@+2],AX ;AN000;
;AN000;
invoke DRIVE_FROM_SFT ; set IFSDRV for possible criter ;AN000;
invoke SFT_TO_SFF ; sets: [THISIFS] ;AN000;
; ES:BX -> IFSRH ;AN000;
; IFSR_OPEN_CB@ ;AN000;
; ds - IFSSEG ;AN000;
;AN000;
invoke CALL_IFS ; *** call fs with read/write request ;AN000;
;AN000;
JNC W_100 ;AN000;
Context DS ; restore ds-dosgroup ;AN001;
LES DI,[THISSFT] ; restore esdi-sft ;AN001;
transfer ifs_1000 ; transfer to general ret as carry set ;AC001;
W_100: ;AN000;
MOV CX,ES:[BX.IFSR_COUNT] ; prep reg output ;AN000;
invoke SFF_TO_SFT ;AN000;
Context DS ; restore ds-dosgroup ;AN001;
LES DI,[THISSFT] ; restore esdi-sft ;AN001;
transfer ifs_990 ; transfer to general good ret in util ;AN001;
;AN000;
EndProc IFS_WRITE ;AN000;
;AN000;
BREAK <IFS_XLOCK Lock a FS SFT> ;AN000;
;AN000;
;****************************************************************************** ;AN000;
; ;AN000;
; IFS_XLOCK ;AN000;
; ;AN000;
; Called by: IFSFUNC dispatcher ;AN000;
; ;AN000;
; Routines called: CALL_IFS DRIVE_FROM_SFT ;AN000;
; SFT_TO_SFF ;AN000;
; SFF_TO_SFT ;AN000;
; ;AN000;
; Inputs: ;AN000;
; BL = 80H bit: 0 lock all operations ;AN000;
; 1 lock write operations only ;AN000;
; 0 Lock
; 1 Unlock
; 2 lock multiple range ;AN000;
; 3 unlock multiple range ;AN000;
; 4 lock/read ;AN000;
; 5 write/unlock ;AN000;
; 6 add (lseek eof/lock/write/unlock) ;AN000;
; ES:DI -> SFT ;AN000;
; CX = count/size Number of ranges/block size ;AN000;
; DS:DX -> BUFFER LABEL DWORD ;AN000;
; DD POSITION ; lock range, repeats CX times ;AN000;
; DD LENGTH ; ;AN000;
; ;AN000;
; ;AN000;
; Function: ;AN000;
; Prep IFSRH: ;AN000;
; * IFSR_LENGTH DW 46+ ; Length of request ;AN000;
; * IFSR_FUNCTION DB 4 ; Execute API function ;AN000;
; + IFSR_RETCODE DW ? ;AN000;
; + IFSR_RETCLASS DB ? ;AN000;
; IFSR_RESV1 DB 16 DUP(0) ;AN000;
; * IFSR_APIFUNC DB 13 ; Lock Function ;AN000;
; + IFSR_ERROR_CLASS DB ? ;AN000;
; + IFSR_ERROR_ACTION DB ? ;AN000;
; + IFSR_ERROR_LOCUS DB ? ;AN000;
; + IFSR_ALLOWED DB ? ;AN000;
; + IFSR_I24_RETRY DB ? ;AN000;
; + IFSR_I24_RESP DB ? ;AN000;
; IFSR_RESV2 DB ? ;AN000;
; *+ IFSR_DEVICE_CB@ DD ? ;AN000;
; *+ IFSR_OPEN_CB@ DD ? ; Call SFT_TO_SFFto convert SFT to SFF ;AN000;
; ; and set this as pointer to it. ;AN000;
; * IFSR_FUNC DB subfunction ; 0=LOCK, 1=UNLOCK ;AN000;
; IFSR_RESV3 DB DOS reserved ;AN000;
; * IFSR_POSITION DD range start ; single range ;AN000;
; * IFSR_LENGTH DD range length ;AN000;
; ;AN000;
; CALL routine, CALL_IFS, with pointer to SF_IFSR_HDR ;AN000;
; IF IFSR_RETCODE = 0 THEN ;AN000;
; DO ;AN000;
; Call SFF_TO_SFT ;AN000;
; Clear carry ;AN000;
; ENDDO ;AN000;
; ELSE DO {error} ;AN000;
; AX = IFSR_RETCODE ;AN000;
; Set carry ;AN000;
; ENDDO ;AN000;
; ENDIF ;AN000;
; ;AN000;
; Outputs: ;AN000;
; AX set on error: Lock conflict ;AN000;
; Too many locks ;AN000;
; ;AN000;
;****************************************************************************** ;AN000;
;AN000;
procedure IFS_XLOCK,NEAR ;AN000;
;AN000;
ifsr_fcn_def EXECAPI ;AN000;
ifsr_api_def LOCKFILE ;AN000;
;AN000;
SaveReg <BX> ; save input bl ;AN014;
MOV CS:IFSPROC_FLAGS,SetDeviceCB ;AC002;
;;;;;;;;TEST BL,80H ;AN006;AD010;
; JZ L_10 ;AN006;AD010;
; OR CS:IFSPROC_FLAGS,IsWOLock ; This is Write Only lock ;AN006;AD010;
;L_10: ;AN006;AD010;
; SaveReg <BX> ; save function (int 21h al value) ;AD010;
; AND BL,07FH ; ditch 80h bit for now ;AD010;
; CMP BL,INT21AL_LOCK_READ ; Check for special case locks ;AD010;
; JB L_60 ; these generate different ;AD010;
; JNE L_20 ; ifsrh's. ;AD010;
; OR CS:IFSPROC_FLAGS,IsLockRead ; This is lock/read request ;AD010;
; RestoreReg <BX> ; restore bx with 80 bit ;AD010;
; Context DS ;AD010;
; JMP R_20 ; let ifs_read above handle this ;AD010;
;L_20: ;AD010;
; CMP BL,INT21AL_WRITE_UNLOCK ;AD010;
; RestoreReg <BX> ; restore bx with 80 bit ;AD010;
; JNE L_40 ;AD010;
; OR CS:IFSPROC_FLAGS,IsWriteUnlock ; This is write/unlock request ;AD010;
; JMP SHORT L_50 ; cont. ifs_write above ;AD010;
;L_40: ;AD010;
; OR IFSPROC_FLAGS,IsAdd ;AD010;
;L_50: ;AD010;
; Context DS ;AD010;
;;;;;;;;JMP W_20 ; cont. in ifs_write above ;AD010;
;AN000;
L_60: ;AN000;
SaveReg <DS> ; save input ds (buffer ptr) ;AN000;
Context DS ; ds-dosgroup to access thissft ;AN000;
MOV WORD PTR [THISSFT],DI ; set [THISSFT] ;AN000;
MOV WORD PTR [THISSFT+2],ES ;AN000;
invoke DRIVE_FROM_SFT ; set IFSDRV for possible criter ;AN000;
invoke PREP_IFSR ; clear ifsrh ;AM003;
MOV CS:DEVICE_CB@_OFFSET,IFSR_DEVICE_CB@ ;AN000;
invoke SFT_TO_SFF ; sets: [THISIFS] ;AN000;
; ES:BX -> IFSRH ;AN000;
; IFSR_OPEN_CB@ ;AN000;
; ds - IFSSEG ;AN000;
MOV ES:[BX.IFSR_LENGTH],LENGTH_LOCKFILE ; prep IFSRH ;AN000;
MOV ES:[BX.IFSR_FUNCTION],IFSEXECAPI ;AN000;
MOV ES:[BX.IFSR_APIFUNC],IFSLOCKFILE ;AN000;
;;;;;;;;MOV ES:[BX.IFSR_COUNT],CX ;AN003;AD010;
RestoreReg <DS> ; range segment, mode (input bl) ;AC003;AC010;
;;;;;;;;MOV AL,CL ;AN003;AD010;
; AND AL,07FH ; mask off hi 80 bit ;AN003;AD010;
; CMP AL,2 ;AN003;AD010;
; JGE L_70 ;AN003;AD010;
; ADD CL,2 ;AN003;AD010;
;L_70: ;AN003;AD010;
; MOV ES:[BX.IFSR_MODE],CL ;AN000;AD010;
; AND ES:[BX.IFSR_MODE],80H ; ditch input bl in low nibble ;AN005;AD010;
; AND CL,07FH ;AN003;AD010;
;;;;;;;;SUB CL,2 ; set func (0-lock,1-unlock) ;AC003;AD010;
RestoreReg <AX> ; restore input bl into al ;AN014;
MOV ES:[BX.IFSR_FUNC],AL ;AC003;AC010;
;;;;;;;;MOV WORD PTR ES:[BX.IFSR_RANGE@],DX ;AD010;
;;;;;;;;MOV WORD PTR ES:[BX.IFSR_RANGE@+2],DS ;AD010;
SaveReg <SI,DX> ;AN010;
RestoreReg <SI> ;AN010;
MOV AX,WORD PTR DS:[SI] ;AN010;
MOV WORD PTR ES:[BX.IFSR_LK_POSITION],AX ;AN010;
MOV AX,WORD PTR DS:[SI+2] ;AN010;
MOV WORD PTR ES:[BX.IFSR_LK_POSITION+2],AX ;AN010;
MOV AX,WORD PTR DS:[SI+4] ;AN010;
MOV WORD PTR ES:[BX.IFSR_LK_LENGTH],AX ;AN010;
MOV AX,WORD PTR DS:[SI+6] ;AN010;
MOV WORD PTR ES:[BX.IFSR_LK_LENGTH+2],AX ;AN010;
RestoreReg <SI>
SaveReg <CS> ; set ds=ifsseg for ifs call ;AN003;
RestoreReg <DS> ;AN003;
invoke CALL_IFS ; *** call fs with lock request ;AN000;
;AN000;
JNC L_100 ;AN000;
transfer ifs_1000 ; go to general return (util) ;AN000;
L_100: ;AN000;
invoke SFF_TO_SFT ;AN000;
transfer ifs_990 ; go to general good ret (util) ;AN000;
;AN000;
;AN000;
EndProc IFS_XLOCK ;AN000;
;AN000;
BREAK <IFS_FILE_XATTRIBUTES Get/Set File Extended Attributes by handle> ;AN000;
;******************************************************************************
;
; IFS_FILE_XATTRIBUTES
;
; Called by: IFSFUNC dispatcher
;
; Routines called: CALL_IFS DRIVE_FROM_SFT
; SFT_TO_SFF
; SFF_TO_SFT
;
; Inputs:
; [THISSFT] Points to SFT being used
; [SAVE_ES:DI] -> Buffer for EA or EA names list
; [SAVE_DS:SI] -> Query List (BL=2)
; [SAVE_CX] = buffer size (BL=2,3)
; BL = function - 2=Get EA
; 3=Get EA Names
; 4=Set EA
;
; Function:
; This call is driven by the new INT 21H call 57H. *** REMOVED
; Prep IFSRH:
; * IFSR_LENGTH DW 50 ; Total length of request
; * IFSR_FUNCTION DB 4 ; Execute API function
; + IFSR_RETCODE DW ?
; + IFSR_RETCLASS DB ?
; IFSR_RESV1 DB 16 DUP(0)
; * IFSR_APIFUNC DB 15 ; File Attributes - get/set by name
; + IFSR_ERROR_CLASS DB ?
; + IFSR_ERROR_ACTION DB ?
; + IFSR_ERROR_LOCUS DB ?
; + IFSR_ALLOWED DB ?
; + IFSR_I24_RETRY DB ?
; + IFSR_I24_RESP DB ?
; IFSR_RESV2 DB ?
; IFSR_DEVICE_CB@ DD ?
; *+ IFSR_OPEN_CB@ DD ?
; * IFSR_FUNC DB ? ; 0-get 1-set
; * IFSR_SUBFUNC DB ? ; 2-EA 3-EA names
; *+ IFSR_BUFFER1@ DD ? ; Query List
; *+ IFSR_BUFFER2@ DD ? ; EA List
; *+ IFSR_COUNT DW ? ; count
;
; CALL routine, CALL_IFS, with pointer to SF_IFSR_HDR
; IF IFSR_RETCODE = 0 THEN
; DO
; Call SFF_TO_SFT
; Clear carry
; ENDDO
; ELSE DO
; AX = IFSR_RETCODE
; Set carry
; ENDDO
; ENDIF
; ENDDO
;
; Outputs:
; Carry clear: On Get:
; QUERY LIST or LIST filled in.
; On Set:
; Extended attributes set. All SFTs are updated.
; CARRY SET
; Carry set: AX is error code
; error_file_not_found
; Last element of path not found
; error_path_not_found
; Bad path (not in curr dir part if present)
; error_access_denied
; Attempt to set an attribute which cannot be set
; (attr_directory, attr_volume_ID)
; error_sharing_violation
; Sharing mode of file did not allow the change
; (this request requires exclusive write/read access)
; (INT 24H generated)
; DS preserved, others destroyed
;
;******************************************************************************
;AN000;
procedure IFS_FILE_XATTRIBUTES,NEAR ;AN000;
;AN000;
;;;;;;;;ifsr_fcn_def EXECAPI ; define ifsr for fileattr ;AN000;
; ifsr_api_def FILEATTR ;AN000;
; ;AN000;
; MOV CS:IFSPROC_FLAGS,SetDeviceCB ; init processing flags ;AN000;
; SaveReg <BX> ; save input function (2,3,4) ;AN000;
; ;AN000;
; invoke PREP_IFSR ; init ifsr ;AN000;
; Context DS ; ds - dosgroup ;AN000;
; ;AN000;
; invoke DRIVE_FROM_SFT ; set IFSDRV for possible criter ;AN000;
; MOV CS:DEVICE_CB@_OFFSET,IFSR_DEVICE_CB@ ;AN000;
; MOV ES:[BX.IFSR_LENGTH],LENGTH_FILEATTR ; prep IFSRH ;AN000;
; MOV ES:[BX.IFSR_FUNCTION],IFSEXECAPI ;AN000;
; MOV ES:[BX.IFSR_APIFUNC],IFSFILEATTR ;AN000;
; MOV AL,FUNC_GET_BY_HANDLE ; start ifsr_func with get ;AN000;
;;;;;;;;RestoreReg <CX> ; get original BX - func ;AN000;
CMP BL,4 ; ;AC010;
JNE XFA_40 ; ;AC010;
JMP C_990 ; just ret success if set ;AC010;
XFA_40: ;AN000;
;;;;;;;;MOV ES:[BX.IFSR_FUNC],AL ;AN000;
; MOV AL,SUBFUNC_EA ; start ifsr_subfunc w/ea list ;AN000;
; CMP CL,3 ; (input get ea names) ;AN000;
; JNE XFA_80 ;AN000;
; INC AL ; inc ifsr_subfunc to ea names ;AN000;
;FA_80: ;AN000;
; MOV ES:[BX.IFSR_SUBFUNC],AL ;AN000;
; CMP CL,4 ; no size offered on set so don't check ;AN009;
; JE XFA_82 ;AN009;
;
;FA_82: ;AN009;
; MOV AX,[SAVE_DI] ;AN000;
; MOV WORD PTR ES:[BX.IFSR_BUFFER2@],AX ; get list ptr into buffer2@ ;AC002;
; MOV AX,[SAVE_ES] ;AN000;
; MOV WORD PTR ES:[BX.IFSR_BUFFER2@+2],AX ; get list ptr into buffer2@ ;AC002;
;FA_85: ;AN008;
; CMP CL,2 ; get ea list with qlist ;AN000;
; JNE XFA_90 ;AN000;
; MOV AX,[SAVE_SI] ;AN000;
; CMP AX,NULL_PTR ; if null, don't set buffer1 ;AN005;
; JE XFA_90 ;AN005;
; MOV WORD PTR ES:[BX.IFSR_BUFFER1@],AX ; get list ptr into buffer2@ ;AC002;
; MOV AX,[SAVE_DS] ;AN000;
; MOV WORD PTR ES:[BX.IFSR_BUFFER1@+2],AX ; get list ptr into buffer2@ ;AC002;
;FA_90: ;AN000;
; PUSH [SAVE_CX] ; buffer size ;AN000;
; POP ES:[BX.IFSR_COUNT] ;AN000;
; invoke SFT_TO_SFF ; sets: [THISIFS] ;AN000;
; ; ES:BX -> IFSRH ;AN000;
; ; IFSR_OPEN_CB@ ;AN000;
; ; ds - IFSSEG ;AN000;
;************************************************
; invoke CALL_IFS ; *** call fs with fileattr request ;AN000;
;************************************************
; JNC XFA_100 ;AN000;
; JMP C_1000 ;AN000;
;FA_100: ;AN000;
;;;;;;;;invoke SFF_TO_SFT ;AN000;
Context DS ; on get - set size to 2 and count=0 ;AN010;
MOV AX,[SAVE_CX] ; if count < 2 than no buffer2 ;AN008;;AC013;
CMP AX,2 ;AN008;;AC013;
JGE XFA_120 ;AN008;;AC013;
XOR AX,AX
JMP SHORT XFA_140
XFA_120: ;AN013;
PUSH [SAVE_ES] ;AN010;
POP ES ;AN010;
MOV DI,[SAVE_DI] ;AN010;
XOR AX,AX ;AN010;
STOSW ; count in buffer ;AN010;
MOV AX,2 ;AN007;AC010;
XFA_140: ;AN013;
SaveReg <AX> ; preserve future cx ;AN016;
CallInstall Get_User_Stack,multDOS,24 ; put size in user cx ;AN007;
RestoreReg <AX> ; restore future cx ;AN016;
MOV DS:[SI.USER_CX],AX ;AN007;
JMP C_990 ; go ret in close to get ds-dosgroup ;AN000;
;AN000;
;AN000;
EndProc IFS_FILE_XATTRIBUTES ;AN000;
;AN000;
;AN000;
IFSSEG ENDS ;AN000;
END ;AN000;
|