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
|
; SCCSID = @(#)open.asm 1.1 85/04/10
TITLE DOS_OPEN - Internal OPEN call for MS-DOS
NAME DOS_OPEN
; Low level routines for openning a file from a file spec.
; Also misc routines for sharing errors
;
; DOS_Open
; Check_Access_AX
; SHARE_ERROR
; SET_SFT_MODE
; Code_Page_Mismatched_Error ; DOS 4.00
;
; Revision history:
;
; Created: ARR 30 March 1983
; A000 version 4.00 Jan. 1988
;
;
; 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
include fastxxxx.inc ;AN000;
include ifssym.inc ;AN000;
.cref
.list
Installed = TRUE
i_need NoSetDir,BYTE
i_need THISSFT,DWORD
i_need THISCDS,DWORD
i_need CURBUF,DWORD
i_need CurrentPDB,WORD
i_need CURR_DIR_END,WORD
I_need RetryCount,WORD
I_need Open_Access,BYTE
I_need fSharing,BYTE
i_need JShare,DWORD
I_need FastOpenFlg,byte
I_need EXTOPEN_ON,BYTE ;AN000;; DOS 4.00
I_need ALLOWED,BYTE ;AN000;; DOS 4.00
I_need EXTERR,WORD ;AN000;; DOS 4.00
I_need EXTERR_LOCUS,BYTE ;AN000;; DOS 4.00
I_need EXTERR_ACTION,BYTE ;AN000;; DOS 4.00
I_need EXTERR_CLASS,BYTE ;AN000;; DOS 4.00
I_need CPSWFLAG,BYTE ;AN000;; DOS 4.00
I_need EXITHOLD,DWORD ;AN000;; DOS 4.00
I_need THISDPB,DWORD ;AN000;; DOS 4.00
I_need SAVE_CX,WORD ;AN000;; DOS 4.00
Break <DOS_Open - internal file access>
; Inputs:
; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL
; terminated)
; [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
; (Low word = -1 if NUL CDS (Net direct request))
; [THISSFT] Points to SFT to fill in if file found
; (sf_mode field set so that FCB may be detected)
; [SATTRIB] Is attribute of search, determines what files can be found
; AX is Access and Sharing mode
; High NIBBLE of AL (Sharing Mode)
; sharing_compat file is opened in compatibility mode
; sharing_deny_none file is opened Multi reader, Multi writer
; sharing_deny_read file is opened Only reader, Multi writer
; sharing_deny_write file is opened Multi reader, Only writer
; sharing_deny_both file is opened Only reader, Only writer
; Low NIBBLE of AL (Access Mode)
; open_for_read file is opened for reading
; open_for_write file is opened for writing
; open_for_both file is opened for both reading and writing.
;
; For FCB SFTs AL should = sharing_compat + open_for_both
; (not checked)
; Function:
; Try to open the specified file
; Outputs:
; sf_ref_count is NOT altered
; CARRY CLEAR
; THISSFT filled in.
; 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_bad_curr_dir
; Bad path in current directory part of path
; error_invalid_access
; Bad sharing mode or bad access mode or bad combination
; error_access_denied
; Attempt to open read only file for writting, or
; open a directory
; error_sharing_violation
; The sharing mode was correct but not allowed
; generates an INT 24 on compatibility mode SFTs
; DS preserved, others destroyed
procedure DOS_Open,NEAR
DOSAssume CS,<DS>,"DOS_Open"
ASSUME ES:NOTHING
MOV [NoSetDir],0
CALL Check_Access_AX
retc
LES DI,[THISSFT]
XOR AH,AH
; sleaze! move only access/sharing mode in. Leave sf_isFCB unchanged
MOV BYTE PTR ES:[DI.sf_mode],AL ; For moment do this on FCBs too
PUSH ES
LES SI,[THISCDS]
CMP SI,-1
JNZ TEST_RE_NET
POP ES
;Extended open hooks
TEST [EXTOPEN_ON],ext_open_on ;FT. from extnded open ;AN000;
JZ NOEXTOP ;FT. no, do normal ;AN000;
IFS_extopen: ;AN000;
MOV AL,byte ptr [SAVE_CX] ;FT. al= create attribute ;AN000;
PUSH AX ;FT. pass create attr to IFS ;AN000;
MOV AX,(multNET SHL 8) OR 46 ;FT. issue extended open verb ;AN000;
INT 2FH ;FT. ;AN000;
POP BX ;FT. trash bx ;AN000;
MOV [EXTOPEN_ON],0 ;FT. ;AN000;
JNC update_size ;IFS. file may be opened ;AN000;
return ;FT. ;AN000;
NOEXTOP:
;Extended open hooks
IF NOT Installed
transfer NET_SEQ_OPEN
ELSE
PUSH AX
MOV AX,(multNET SHL 8) OR 22
INT 2FH
POP BX ; clean stack
return
ENDIF
TEST_RE_NET:
TEST ES:[SI.curdir_flags],curdir_isnet
POP ES
JZ LOCAL_OPEN
; CALL IFS_SHARE_CHECK ;IFS. check IFS share,may create share ;AN000;
; JC nomore ;IFS. share violation ;AN000;
;Extended open hooks
TEST [EXTOPEN_ON],ext_open_on ;FT. from extnded open ;AN000;
JNZ IFS_extopen ;FT. isuue extended open ;AN000;
;Extended open hooks
IF NOT Installed
transfer NET_OPEN
ELSE
PUSH AX
MOV AX,(multNET SHL 8) OR 22
INT 2FH
POP BX ; clean stack
; JC nomore ;IFS. error ;AN000;
update_size: ;AN000;
; CALL OWN_SHARE ;IFS. IFS owns share ? ;AN000;
; JZ nomore2 ;IFS. yes ;AN000;
; MOV AX,3 ;IFS. update file size for all SFT ;AN000;
; LES DI,ThisSFT ;IFS. ;AN000;
; call JShare + 14 * 4 ;IFS. call ShSu ;AN000;
nomore2:
; CLC
nomore:
return
ENDIF
LOCAL_OPEN:
EnterCrit critDisk
; DOS 3.3 FastOPen 6/16/86
OR [FastOpenFlg],FastOpen_Set+Special_Fill_Set ; only open can
invoke GetPath
; DOS 3.3 FastOPen 6/16/86
JNC Open_found
JNZ bad_path
OR CL,CL
JZ bad_path
OpenFNF:
MOV AX,error_file_not_found
OpenBadRet:
AND BYTE PTR CS:[FastOpenFlg],Fast_yes ;; DOS 3.3
STC
LeaveCrit critDisk
JMP Clear_FastOpen
bad_path:
MOV AX,error_path_not_found
JMP OpenBadRet
open_bad_access:
MOV AX,error_access_denied
JMP OpenBadRet
Open_found:
JZ Open_Bad_Access ; test for directories
OR AH,AH
JS open_ok ; Devices don't have attributes
MOV ES,WORD PTR [CURBUF+2] ; get buffer location
MOV AL,ES:[BX].dir_attr
TEST AL,attr_volume_id ; can't open volume ids
JNZ open_bad_access
TEST AL,attr_read_only ; check write on read only
JZ open_ok
;
; The file is marked READ-ONLY. We verify that the open mode allows access to
; the read-only file. Unfortunately, with FCB's and net-FCB's we cannot
; determine at the OPEN time if such access is allowed. Thus, we defer such
; processing until the actual write operation:
;
; If FCB, then we change the mode to be read_only.
; If net_FCB, then we change the mode to be read_only.
; If not open for read then error.
;
SaveReg <DS,SI>
LDS SI,[THISSFT]
MOV CX,[SI].sf_mode
TEST CX,sf_isFCB ; is it FCB?
JNZ ResetAccess ; yes, reset the access
MOV DL,CL
AND DL,sharing_mask
CMP DL,sharing_net_FCB ; is it net FCB?
JNZ NormalOpen ; no
ResetAccess:
AND CX,NOT access_mask ; clear access
errnz open_for_read
; OR CX,open_for_read ; stick in open_for_read
MOV [SI].sf_mode,CX
JMP SHORT FillSFT
;
; The SFT is normal. See if the requested access is open_for_read
;
NormalOpen:
AND CL,access_mask ; remove extras
CMP CL,open_for_read ; is it open for read?
JZ FillSFT
RestoreReg <SI,DS>
JMP short open_bad_access
;
; All done, restore registers and fill the SFT.
;
FillSFT:
RestoreReg <SI,DS>
open_ok:
;;; File Tagging DOS 4.00
; OR AH,AH ;FT. device ? ;AN000;
; JS NORM0 ;FT. yes, don't do code page matching ;AN000;
; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000;
; JZ NORM0 ;FT. no ;AN000;
; CMP ES:[BX].dir_CODEPG,0 ;FT. code page 0 ;AN000;
; JZ NORM0 ;FT. yes do nothing ;AN000;
; PUSH AX ;FT. ;AN000;
; invoke Get_Global_CdPg ;FT. get global code page ;AN000;
; CMP ES:[BX].dir_CODEPG,AX ;FT. equal to global code page ;AN000;
; JZ NORM1 ;FT. yes ;AN000;
; call Code_Page_Mismatched_Error ;FT. ;AN000;
; CMP AL,0 ;FT. ignore ? ;AN000;
; JZ NORM1 ;FT. ;AN000;
; POP AX ;FT. ;AN000;
; JMP open_bad_access ;FT. set carry and return ;AN000;
NORM1: ;AN000;
; POP AX ;FT. ;AN000;
NORM0:
;;; File Tagging DOS 4.00
invoke DOOPEN ; Fill in SFT
AND BYTE PTR CS:[FastOpenFlg],Fast_yes ;; DOS 3.3
CALL DO_SHARE_CHECK ;
JNC Share_Ok
LeaveCrit critDisk
JMP Clear_FastOPen
SHARE_OK:
MOV AX,3
LES DI,ThisSFT
if installed
call JShare + 14 * 4
else
Call ShSU
endif
;; DOS 4.00 10/27/86
LES DI,ThisSFT ; if this is a newly ;AN000;
CMP ES:[DI.sf_firclus],0 ; created file then ;AN000;
JZ no_fastseek ; do nothing ;AN000;
MOV CX,ES:[DI.sf_firclus] ; first cluster # ;AN000;
LES DI,ES:[DI.sf_devptr] ; pointer to DPB ;AN000;
MOV DL,ES:[DI.dpb_drive] ; drive # ;AN000;
invoke FastSeek_Open ; call fastseek ;AN000;
no_fastseek:
;; DOS 4.00 10/27/86
LeaveCrit critDisk
;
; Finish SFT initialization for new reference. Set the correct mode.
;
; Inputs:
; ThisSFT points to SFT
;
; Outputs:
; Carry clear
; Registers modified: AX.
entry SET_SFT_MODE
DOSAssume CS,<DS>,"Set_SFT_Mode"
ASSUME ES:NOTHING
LES DI,ThisSFT
invoke DEV_OPEN_SFT
TEST ES:[DI.sf_mode],sf_isfcb; Clears carry
retz ; sf_mode correct
MOV AX,[CurrentPDB]
MOV ES:[DI.sf_PID],AX ; For FCB sf_PID=PID
Clear_FastOpen:
return ;;;;; DOS 3.3
EndProc DOS_Open
; Called on sharing violations. ES:DI points to SFT. AX has error code
; If SFT is FCB or compatibility mode gens INT 24 error.
; Returns carry set AX=error_sharing_violation if user says ignore (can't
; really ignore). Carry clear
; if user wants a retry. ES, DI, DS preserved
procedure SHARE_ERROR,NEAR
DOSAssume CS,<DS>,"Share_Error"
ASSUME ES:NOTHING
TEST ES:[DI.sf_mode],sf_isfcb
JNZ HARD_ERR
MOV CL,BYTE PTR ES:[DI.sf_mode]
AND CL,sharing_mask
CMP CL,sharing_compat
JNE NO_HARD_ERR
HARD_ERR:
invoke SHARE_VIOLATION
retnc ; User wants retry
NO_HARD_ERR:
MOV AX,error_sharing_violation
STC
return
EndProc SHARE_ERROR
; Input: THISDPB, WFP_Start, THISSFT set
; Functions: check file sharing mode is valid
; Output: carry set, error
; carry clear, share ok
procedure DO_SHARE_CHECK,NEAR
DOSAssume CS,<DS>,"DO_SHARE__CHECK"
ASSUME ES:NOTHING
EnterCrit critDisk ; enter critical section
OPN_RETRY:
MOV CX,RetryCount ; Get # tries to do
OpenShareRetry:
SaveReg <CX> ; Save number left to do
invoke SHARE_CHECK ; Final Check
RestoreReg <CX> ; CX = # left
JNC Share_Ok2 ; No problem with access
Invoke Idle
LOOP OpenShareRetry ; One more retry used up
OpenShareFail:
LES DI,[ThisSft]
invoke SHARE_ERROR
JNC OPN_RETRY ; User wants more retry
Share_Ok2:
LeaveCrit critDisk ; leave critical section
return
EndProc DO_SHARE_CHECK
; Input: ES:DI -> SFT
; Functions: check if IFS owns SHARE
; Output: Zero set, use IFS SHARE
; otherwise, use DOS SHARE
procedure OWN_SHARE,NEAR ;AN000;
DOSAssume CS,<DS>,"OWN_SHARE" ;AN000;
ASSUME ES:NOTHING ;AN000;
; PUSH DS ;IFS. save reg ;AN000;
; PUSH SI ;IFS. save reg ;AN000;
; LDS SI,ES:[DI.sf_IFS_HDR] ;IFS. ds:si-> IFS header ;AN000;
; TEST [SI.IFS_ATTRIBUTE],IFSUSESHARE ;IFS. save reg ;AN000;
; POP SI ;IFS. retore reg ;AN000;
; POP DS ;IFS. restore reg ;AN000;
return ;IFS. return ;AN000;
EndProc OWN_SHARE ;AN000;
; Input: THISCDS -> CDS
; Functions: check if IFS owns SHARE
; Output: Zero set, use IFS SHARE
; otherwise, use DOS SHARE
procedure OWN_SHARE2,NEAR ;AN000;
DOSAssume CS,<DS>,"OWN_SHARE2" ;AN000;
ASSUME ES:NOTHING ;AN000;
; CMP WORD PTR [THISCDS],-1 ;IFS. UNC ? ;AN000;
; JZ ifs_hasit ;IFS. yes ;AN000;
; PUSH DS ;IFS. save reg ;AN000;
; PUSH SI ;IFS. save reg ;AN000;
; LDS SI,[THISCDS] ;IFS. DS:SI -> ThisCDS ;AN000;
; LDS SI,[SI.curdir_IFS_HDR] ;IFS. ds:si-> IFS header ;AN000;
; TEST [SI.IFS_ATTRIBUTE],IFSUSESHARE ;IFS. ;AN000;
; POP SI ;IFS. retore reg ;AN000;
; POP DS ;IFS. restore reg ;AN000;
ifs_hasit: ;AN000;
return ;IFS. return ;AN000;
EndProc OWN_SHARE2 ;AN000;
; Input: ES:DI -> SFT
; Functions: set THISDPB
; Output: none
procedure SET_THISDPB,NEAR ;AN000;
DOSAssume CS,<DS>,"SET_THISDPB" ;AN000;
ASSUME ES:NOTHING ;AN000;
; PUSH DS ;IFS. save reg ;AN000;
; PUSH SI ;IFS. save reg ;AN000;
; LDS SI,[THISCDS] ;IFS. ds:si-> CDS ;AN000;
; LDS SI,[SI.CURDIR_DEVPTR] ;IFS. ds:si-> DPB ;AN000;
; MOV WORD PTR [THISDPB],SI ;IFS. set THISDPB ;AN000;
; MOV WORD PTR [THISDPB+2],DS ;IFS. ;AN000;
; POP SI ;IFS. retore reg ;AN000;
; POP DS ;IFS. restore reg ;AN000;
return ;IFS. return ;AN000;
EndProc SET_THISDPB ;AN000;
; Input: ES:DI -> SFT
; Functions: check IFS share
; Output: none
procedure IFS_SHARE_CHECK,NEAR ;AN000;
DOSAssume CS,<DS>,"IFS_SHARE_CHECK" ;AN000;
ASSUME ES:NOTHING ;AN000;
; CALL OWN_SHARE ;IFS. IFS owns share ;AN000;
; JZ IFSSHARE ;IFS. yes ;AN000;
; PUSH AX ;IFS. save mode ;AN000;
; CALL SET_THISDPB ;IFS. set THISDPB for SHARE_VIOLATION ;AN000;
; CALL DO_SHARE_CHECK ;IFS. check share ;AN000;
; POP AX ;IFS. restore mode and share ok ;AN000;
IFSSHARE: ;AN000;
return ;IFS. return ;AN000;
EndProc IFS_SHARE_CHECK ;AN000;
; Inputs:
; AX is mode
; High NIBBLE of AL (Sharing Mode)
; sharing_compat file is opened in compatibility mode
; sharing_deny_none file is opened Multi reader, Multi writer
; sharing_deny_read file is opened Only reader, Multi writer
; sharing_deny_write file is opened Multi reader, Only writer
; sharing_deny_both file is opened Only reader, Only writer
; Low NIBBLE of AL (Access Mode)
; open_for_read file is opened for reading
; open_for_write file is opened for writing
; open_for_both file is opened for both reading and writing.
; Function:
; Check this access mode for correctness
; Outputs:
; [open_access] = AL input
; Carry Clear
; Mode is correct
; AX unchanged
; Carry Set
; Mode is bad
; AX = error_invalid_access
; No other registers effected
procedure Check_Access_AX
DOSAssume CS,<DS>,"Check_Access"
ASSUME ES:NOTHING
MOV Open_Access,AL
PUSH BX
;
; If sharing, then test for special sharing mode for FCBs
;
MOV BL,AL
AND BL,sharing_mask
CMP fSharing,-1
JNZ CheckShareMode ; not through server call, must be ok
CMP BL,sharing_NET_FCB
JZ CheckAccessMode ; yes, we have an FCB
CheckShareMode:
CMP BL,40h ; is this a good sharing mode?
JA Make_Bad_Access
CheckAccessMode:
MOV BL,AL
AND BL,access_mask
CMP BL,2
JA Make_Bad_Access
POP BX
CLC
return
make_bad_access:
MOV AX,error_invalid_access
POP BX
STC
return
EndProc Check_Access_AX
; Input: none
; Function: Issue Code Page Mismatched INT 24 Critical Error
; OutPut: AL =0 ignore
; =3 fail
procedure Code_Page_Mismatched_Error,NEAR ;AN000;
DOSAssume CS,<DS>,"Code_Page_Mismatched_Error" ;AN000;
ASSUME ES:NOTHING ;AN000;
; PUSH DS ;FT. ;AN000;
; Context DS ;FT. ds=cs ;AN000;
; MOV AH,0A9H ;FT. fail,ignore,device,write ;AN000;
; MOV DI,error_I24_gen_failure ;FT. set error ;AN000;
; MOV [EXTERR],error_Code_Page_Mismatched ;FT. ;AN000;
; MOV [EXTERR_CLASS],errCLASS_NotFnd ;FT. ;AN000;
; MOV [EXTERR_ACTION],errACT_Abort ;FT. ;AN000;
; MOV [EXTERR_LOCUS],errLOC_Unk ;FT. ;AN000;
; MOV word ptr [EXITHOLD + 2],ES ;FT. save es:bp ;AN000;
; MOV word ptr [EXITHOLD],BP ;FT. ;AN000;
; invoke NET_I24_ENTRY ;FT. issue int 24H ;AN000;
; POP DS ;FT. ;AN000;
; return ;FT. ;AN000;
EndProc Code_Page_Mismatched_Error ;AN000;
CODE ENDS
END
|