1 ; SCCSID = @(#)open.asm 1.1 85/04/10
2 TITLE DOS_OPEN
- Internal OPEN
call for
MS-DOS
4 ; Low level routines for openning a file from a file spec.
5 ; Also misc routines for sharing errors
11 ; Code_Page_Mismatched_Error ; DOS 4.00
15 ; Created: ARR 30 March 1983
16 ; A000 version 4.00 Jan. 1988
20 ; get the appropriate segment definitions
25 CODE SEGMENT BYTE PUBLIC 'CODE'
26 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
32 include fastxxxx
.inc ;AN000;
33 include ifssym
.inc ;AN000;
43 i_need CurrentPDB
,WORD
44 i_need CURR_DIR_END
,WORD
45 I_need RetryCount
,WORD
46 I_need Open_Access
,BYTE
49 I_need FastOpenFlg
,byte
50 I_need EXTOPEN_ON
,BYTE ;AN000;; DOS 4.00
51 I_need ALLOWED
,BYTE ;AN000;; DOS 4.00
52 I_need EXTERR
,WORD ;AN000;; DOS 4.00
53 I_need EXTERR_LOCUS
,BYTE ;AN000;; DOS 4.00
54 I_need EXTERR_ACTION
,BYTE ;AN000;; DOS 4.00
55 I_need EXTERR_CLASS
,BYTE ;AN000;; DOS 4.00
56 I_need CPSWFLAG
,BYTE ;AN000;; DOS 4.00
57 I_need EXITHOLD
,DWORD ;AN000;; DOS 4.00
58 I_need THISDPB
,DWORD ;AN000;; DOS 4.00
59 I_need SAVE_CX
,WORD ;AN000;; DOS 4.00
61 Break <DOS_Open
- internal
file access
>
64 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL
66 ; [CURR_DIR_END] Points to end of Current dir part of string
67 ; ( = -1 if current dir not involved, else
68 ; Points to first char after last "/" of current dir part)
69 ; [THISCDS] Points to CDS being used
70 ; (Low word = -1 if NUL CDS (Net direct request))
71 ; [THISSFT] Points to SFT to fill in if file found
72 ; (sf_mode field set so that FCB may be detected)
73 ; [SATTRIB] Is attribute of search, determines what files can be found
74 ; AX is Access and Sharing mode
75 ; High NIBBLE of AL (Sharing Mode)
76 ; sharing_compat file is opened in compatibility mode
77 ; sharing_deny_none file is opened Multi reader, Multi writer
78 ; sharing_deny_read file is opened Only reader, Multi writer
79 ; sharing_deny_write file is opened Multi reader, Only writer
80 ; sharing_deny_both file is opened Only reader, Only writer
81 ; Low NIBBLE of AL (Access Mode)
82 ; open_for_read file is opened for reading
83 ; open_for_write file is opened for writing
84 ; open_for_both file is opened for both reading and writing.
86 ; For FCB SFTs AL should = sharing_compat + open_for_both
89 ; Try to open the specified file
91 ; sf_ref_count is NOT altered
96 ; error_file_not_found
97 ; Last element of path not found
98 ; error_path_not_found
99 ; Bad path (not in curr dir part if present)
101 ; Bad path in current directory part of path
102 ; error_invalid_access
103 ; Bad sharing mode or bad access mode or bad combination
104 ; error_access_denied
105 ; Attempt to open read only file for writting, or
107 ; error_sharing_violation
108 ; The sharing mode was correct but not allowed
109 ; generates an INT 24 on compatibility mode SFTs
110 ; DS preserved, others destroyed
112 procedure DOS_Open
,NEAR
113 DOSAssume
CS,<DS>,"DOS_Open"
121 ; sleaze! move only access/sharing mode in. Leave sf_isFCB unchanged
122 MOV BYTE PTR ES:[DI.sf_mode
],AL ; For moment do this on FCBs too
130 TEST [EXTOPEN_ON
],ext_open_on
;FT. from extnded open ;AN000;
131 JZ NOEXTOP
;FT. no, do normal ;AN000;
133 MOV AL,byte ptr [SAVE_CX
] ;FT. al= create attribute ;AN000;
134 PUSH AX ;FT. pass create attr to IFS ;AN000;
135 MOV AX,(multNET
SHL 8) OR 46 ;FT. issue extended open verb ;AN000;
137 POP BX ;FT. trash bx ;AN000;
138 MOV [EXTOPEN_ON
],0 ;FT. ;AN000;
139 JNC update_size
;IFS. file may be opened ;AN000;
146 transfer NET_SEQ_OPEN
149 MOV AX,(multNET
SHL 8) OR 22
156 TEST ES:[SI.curdir_flags
],curdir_isnet
159 ; CALL IFS_SHARE_CHECK ;IFS. check IFS share,may create share ;AN000;
160 ; JC nomore ;IFS. share violation ;AN000;
163 TEST [EXTOPEN_ON
],ext_open_on
;FT. from extnded open ;AN000;
164 JNZ IFS_extopen
;FT. isuue extended open ;AN000;
171 MOV AX,(multNET
SHL 8) OR 22
174 ; JC nomore ;IFS. error ;AN000;
176 ; CALL OWN_SHARE ;IFS. IFS owns share ? ;AN000;
177 ; JZ nomore2 ;IFS. yes ;AN000;
178 ; MOV AX,3 ;IFS. update file size for all SFT ;AN000;
179 ; LES DI,ThisSFT ;IFS. ;AN000;
180 ; call JShare + 14 * 4 ;IFS. call ShSu ;AN000;
190 ; DOS 3.3 FastOPen 6/16/86
192 OR [FastOpenFlg
],FastOpen_Set
+Special_Fill_Set
; only open can
196 ; DOS 3.3 FastOPen 6/16/86
203 MOV AX,error_file_not_found
205 AND BYTE PTR CS:[FastOpenFlg
],Fast_yes
;; DOS 3.3
211 MOV AX,error_path_not_found
215 MOV AX,error_access_denied
219 JZ Open_Bad_Access
; test for directories
221 JS open_ok
; Devices don't have attributes
222 MOV ES,WORD PTR [CURBUF
+2] ; get buffer location
223 MOV AL,ES:[BX].dir_attr
224 TEST AL,attr_volume_id
; can't open volume ids
226 TEST AL,attr_read_only
; check write on read only
229 ; The file is marked READ-ONLY. We verify that the open mode allows access to
230 ; the read-only file. Unfortunately, with FCB's and net-FCB's we cannot
231 ; determine at the OPEN time if such access is allowed. Thus, we defer such
232 ; processing until the actual write operation:
234 ; If FCB, then we change the mode to be read_only.
235 ; If net_FCB, then we change the mode to be read_only.
236 ; If not open for read then error.
241 TEST CX,sf_isFCB
; is it FCB?
242 JNZ ResetAccess
; yes, reset the access
245 CMP DL,sharing_net_FCB
; is it net FCB?
248 AND CX,NOT access_mask
; clear access
250 ; OR CX,open_for_read ; stick in open_for_read
254 ; The SFT is normal. See if the requested access is open_for_read
257 AND CL,access_mask
; remove extras
258 CMP CL,open_for_read
; is it open for read?
261 JMP short open_bad_access
263 ; All done, restore registers and fill the SFT.
268 ;;; File Tagging DOS 4.00
269 ; OR AH,AH ;FT. device ? ;AN000;
270 ; JS NORM0 ;FT. yes, don't do code page matching ;AN000;
271 ; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000;
272 ; JZ NORM0 ;FT. no ;AN000;
273 ; CMP ES:[BX].dir_CODEPG,0 ;FT. code page 0 ;AN000;
274 ; JZ NORM0 ;FT. yes do nothing ;AN000;
275 ; PUSH AX ;FT. ;AN000;
276 ; invoke Get_Global_CdPg ;FT. get global code page ;AN000;
277 ; CMP ES:[BX].dir_CODEPG,AX ;FT. equal to global code page ;AN000;
278 ; JZ NORM1 ;FT. yes ;AN000;
279 ; call Code_Page_Mismatched_Error ;FT. ;AN000;
280 ; CMP AL,0 ;FT. ignore ? ;AN000;
281 ; JZ NORM1 ;FT. ;AN000;
282 ; POP AX ;FT. ;AN000;
283 ; JMP open_bad_access ;FT. set carry and return ;AN000;
285 ; POP AX ;FT. ;AN000;
288 ;;; File Tagging DOS 4.00
289 invoke DOOPEN
; Fill in SFT
290 AND BYTE PTR CS:[FastOpenFlg
],Fast_yes
;; DOS 3.3
291 CALL DO_SHARE_CHECK
;
305 LES DI,ThisSFT
; if this is a newly ;AN000;
306 CMP ES:[DI.sf_firclus
],0 ; created file then ;AN000;
307 JZ no_fastseek
; do nothing ;AN000;
308 MOV CX,ES:[DI.sf_firclus
] ; first cluster # ;AN000;
309 LES DI,ES:[DI.sf_devptr
] ; pointer to DPB ;AN000;
310 MOV DL,ES:[DI.dpb_drive
] ; drive # ;AN000;
311 invoke FastSeek_Open
; call fastseek ;AN000;
319 ; Finish SFT initialization for new reference. Set the correct mode.
322 ; ThisSFT points to SFT
326 ; Registers modified: AX.
329 DOSAssume
CS,<DS>,"Set_SFT_Mode"
334 TEST ES:[DI.sf_mode
],sf_isfcb
; Clears carry
335 retz
; sf_mode correct
337 MOV ES:[DI.sf_PID
],AX ; For FCB sf_PID=PID
344 ; Called on sharing violations. ES:DI points to SFT. AX has error code
345 ; If SFT is FCB or compatibility mode gens INT 24 error.
346 ; Returns carry set AX=error_sharing_violation if user says ignore (can't
347 ; really ignore). Carry clear
348 ; if user wants a retry. ES, DI, DS preserved
350 procedure SHARE_ERROR
,NEAR
351 DOSAssume
CS,<DS>,"Share_Error"
353 TEST ES:[DI.sf_mode
],sf_isfcb
355 MOV CL,BYTE PTR ES:[DI.sf_mode
]
357 CMP CL,sharing_compat
360 invoke SHARE_VIOLATION
361 retnc
; User wants retry
363 MOV AX,error_sharing_violation
370 ; Input: THISDPB, WFP_Start, THISSFT set
371 ; Functions: check file sharing mode is valid
372 ; Output: carry set, error
373 ; carry clear, share ok
375 procedure DO_SHARE_CHECK
,NEAR
376 DOSAssume
CS,<DS>,"DO_SHARE__CHECK"
378 EnterCrit critDisk
; enter critical section
381 MOV CX,RetryCount
; Get # tries to do
383 SaveReg
<CX> ; Save number left to do
384 invoke SHARE_CHECK
; Final Check
385 RestoreReg
<CX> ; CX = # left
386 JNC Share_Ok2
; No problem with access
388 LOOP OpenShareRetry
; One more retry used up
392 JNC OPN_RETRY
; User wants more retry
394 LeaveCrit critDisk
; leave critical section
397 EndProc DO_SHARE_CHECK
400 ; Input: ES:DI -> SFT
401 ; Functions: check if IFS owns SHARE
402 ; Output: Zero set, use IFS SHARE
403 ; otherwise, use DOS SHARE
405 procedure OWN_SHARE
,NEAR ;AN000;
406 DOSAssume
CS,<DS>,"OWN_SHARE" ;AN000;
407 ASSUME
ES:NOTHING
;AN000;
409 ; PUSH DS ;IFS. save reg ;AN000;
410 ; PUSH SI ;IFS. save reg ;AN000;
411 ; LDS SI,ES:[DI.sf_IFS_HDR] ;IFS. ds:si-> IFS header ;AN000;
412 ; TEST [SI.IFS_ATTRIBUTE],IFSUSESHARE ;IFS. save reg ;AN000;
413 ; POP SI ;IFS. retore reg ;AN000;
414 ; POP DS ;IFS. restore reg ;AN000;
415 return
;IFS. return ;AN000;
417 EndProc OWN_SHARE
;AN000;
420 ; Input: THISCDS -> CDS
421 ; Functions: check if IFS owns SHARE
422 ; Output: Zero set, use IFS SHARE
423 ; otherwise, use DOS SHARE
425 procedure OWN_SHARE2
,NEAR ;AN000;
426 DOSAssume
CS,<DS>,"OWN_SHARE2" ;AN000;
427 ASSUME
ES:NOTHING
;AN000;
429 ; CMP WORD PTR [THISCDS],-1 ;IFS. UNC ? ;AN000;
430 ; JZ ifs_hasit ;IFS. yes ;AN000;
431 ; PUSH DS ;IFS. save reg ;AN000;
432 ; PUSH SI ;IFS. save reg ;AN000;
433 ; LDS SI,[THISCDS] ;IFS. DS:SI -> ThisCDS ;AN000;
434 ; LDS SI,[SI.curdir_IFS_HDR] ;IFS. ds:si-> IFS header ;AN000;
435 ; TEST [SI.IFS_ATTRIBUTE],IFSUSESHARE ;IFS. ;AN000;
436 ; POP SI ;IFS. retore reg ;AN000;
437 ; POP DS ;IFS. restore reg ;AN000;
439 return
;IFS. return ;AN000;
441 EndProc OWN_SHARE2
;AN000;
444 ; Input: ES:DI -> SFT
445 ; Functions: set THISDPB
448 procedure SET_THISDPB
,NEAR ;AN000;
449 DOSAssume
CS,<DS>,"SET_THISDPB" ;AN000;
450 ASSUME
ES:NOTHING
;AN000;
452 ; PUSH DS ;IFS. save reg ;AN000;
453 ; PUSH SI ;IFS. save reg ;AN000;
454 ; LDS SI,[THISCDS] ;IFS. ds:si-> CDS ;AN000;
455 ; LDS SI,[SI.CURDIR_DEVPTR] ;IFS. ds:si-> DPB ;AN000;
456 ; MOV WORD PTR [THISDPB],SI ;IFS. set THISDPB ;AN000;
457 ; MOV WORD PTR [THISDPB+2],DS ;IFS. ;AN000;
458 ; POP SI ;IFS. retore reg ;AN000;
459 ; POP DS ;IFS. restore reg ;AN000;
460 return
;IFS. return ;AN000;
462 EndProc SET_THISDPB
;AN000;
465 ; Input: ES:DI -> SFT
466 ; Functions: check IFS share
469 procedure IFS_SHARE_CHECK
,NEAR ;AN000;
470 DOSAssume
CS,<DS>,"IFS_SHARE_CHECK" ;AN000;
471 ASSUME
ES:NOTHING
;AN000;
474 ; CALL OWN_SHARE ;IFS. IFS owns share ;AN000;
475 ; JZ IFSSHARE ;IFS. yes ;AN000;
476 ; PUSH AX ;IFS. save mode ;AN000;
477 ; CALL SET_THISDPB ;IFS. set THISDPB for SHARE_VIOLATION ;AN000;
478 ; CALL DO_SHARE_CHECK ;IFS. check share ;AN000;
479 ; POP AX ;IFS. restore mode and share ok ;AN000;
481 return
;IFS. return ;AN000;
483 EndProc IFS_SHARE_CHECK
;AN000;
487 ; High NIBBLE of AL (Sharing Mode)
488 ; sharing_compat file is opened in compatibility mode
489 ; sharing_deny_none file is opened Multi reader, Multi writer
490 ; sharing_deny_read file is opened Only reader, Multi writer
491 ; sharing_deny_write file is opened Multi reader, Only writer
492 ; sharing_deny_both file is opened Only reader, Only writer
493 ; Low NIBBLE of AL (Access Mode)
494 ; open_for_read file is opened for reading
495 ; open_for_write file is opened for writing
496 ; open_for_both file is opened for both reading and writing.
498 ; Check this access mode for correctness
500 ; [open_access] = AL input
506 ; AX = error_invalid_access
507 ; No other registers effected
509 procedure Check_Access_AX
510 DOSAssume
CS,<DS>,"Check_Access"
516 ; If sharing, then test for special sharing mode for FCBs
521 JNZ CheckShareMode
; not through server call, must be ok
522 CMP BL,sharing_NET_FCB
523 JZ CheckAccessMode
; yes, we have an FCB
525 CMP BL,40h
; is this a good sharing mode?
537 MOV AX,error_invalid_access
542 EndProc Check_Access_AX
545 ; Function: Issue Code Page Mismatched INT 24 Critical Error
546 ; OutPut: AL =0 ignore
549 procedure Code_Page_Mismatched_Error
,NEAR ;AN000;
550 DOSAssume
CS,<DS>,"Code_Page_Mismatched_Error" ;AN000;
551 ASSUME
ES:NOTHING
;AN000;
553 ; PUSH DS ;FT. ;AN000;
554 ; Context DS ;FT. ds=cs ;AN000;
555 ; MOV AH,0A9H ;FT. fail,ignore,device,write ;AN000;
556 ; MOV DI,error_I24_gen_failure ;FT. set error ;AN000;
557 ; MOV [EXTERR],error_Code_Page_Mismatched ;FT. ;AN000;
558 ; MOV [EXTERR_CLASS],errCLASS_NotFnd ;FT. ;AN000;
559 ; MOV [EXTERR_ACTION],errACT_Abort ;FT. ;AN000;
560 ; MOV [EXTERR_LOCUS],errLOC_Unk ;FT. ;AN000;
561 ; MOV word ptr [EXITHOLD + 2],ES ;FT. save es:bp ;AN000;
562 ; MOV word ptr [EXITHOLD],BP ;FT. ;AN000;
563 ; invoke NET_I24_ENTRY ;FT. issue int 24H ;AN000;
564 ; POP DS ;FT. ;AN000;
565 ; return ;FT. ;AN000;
567 EndProc Code_Page_Mismatched_Error
;AN000;