]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/OPEN.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / OPEN.ASM
1 ; SCCSID = @(#)open.asm 1.1 85/04/10
2 TITLE DOS_OPEN - Internal OPEN call for MS-DOS
3 NAME DOS_OPEN
4 ; Low level routines for openning a file from a file spec.
5 ; Also misc routines for sharing errors
6 ;
7 ; DOS_Open
8 ; Check_Access_AX
9 ; SHARE_ERROR
10 ; SET_SFT_MODE
11 ; Code_Page_Mismatched_Error ; DOS 4.00
12 ;
13 ; Revision history:
14 ;
15 ; Created: ARR 30 March 1983
16 ; A000 version 4.00 Jan. 1988
17 ;
18
19 ;
20 ; get the appropriate segment definitions
21 ;
22 .xlist
23 include dosseg.asm
24
25 CODE SEGMENT BYTE PUBLIC 'CODE'
26 ASSUME SS:DOSGROUP,CS:DOSGROUP
27
28 .xcref
29 include dossym.inc
30 include devsym.inc
31 include fastopen.inc
32 include fastxxxx.inc ;AN000;
33 include ifssym.inc ;AN000;
34 .cref
35 .list
36
37 Installed = TRUE
38
39 i_need NoSetDir,BYTE
40 i_need THISSFT,DWORD
41 i_need THISCDS,DWORD
42 i_need CURBUF,DWORD
43 i_need CurrentPDB,WORD
44 i_need CURR_DIR_END,WORD
45 I_need RetryCount,WORD
46 I_need Open_Access,BYTE
47 I_need fSharing,BYTE
48 i_need JShare,DWORD
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
60
61 Break <DOS_Open - internal file access>
62
63 ; Inputs:
64 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL
65 ; terminated)
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.
85 ;
86 ; For FCB SFTs AL should = sharing_compat + open_for_both
87 ; (not checked)
88 ; Function:
89 ; Try to open the specified file
90 ; Outputs:
91 ; sf_ref_count is NOT altered
92 ; CARRY CLEAR
93 ; THISSFT filled in.
94 ; CARRY SET
95 ; AX is error code
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)
100 ; error_bad_curr_dir
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
106 ; open a directory
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
111
112 procedure DOS_Open,NEAR
113 DOSAssume CS,<DS>,"DOS_Open"
114 ASSUME ES:NOTHING
115
116 MOV [NoSetDir],0
117 CALL Check_Access_AX
118 retc
119 LES DI,[THISSFT]
120 XOR AH,AH
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
123 PUSH ES
124 LES SI,[THISCDS]
125 CMP SI,-1
126 JNZ TEST_RE_NET
127 POP ES
128 ;Extended open hooks
129
130 TEST [EXTOPEN_ON],ext_open_on ;FT. from extnded open ;AN000;
131 JZ NOEXTOP ;FT. no, do normal ;AN000;
132 IFS_extopen: ;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;
136 INT 2FH ;FT. ;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;
140 return ;FT. ;AN000;
141 NOEXTOP:
142 ;Extended open hooks
143
144
145 IF NOT Installed
146 transfer NET_SEQ_OPEN
147 ELSE
148 PUSH AX
149 MOV AX,(multNET SHL 8) OR 22
150 INT 2FH
151 POP BX ; clean stack
152 return
153 ENDIF
154
155 TEST_RE_NET:
156 TEST ES:[SI.curdir_flags],curdir_isnet
157 POP ES
158 JZ LOCAL_OPEN
159 ; CALL IFS_SHARE_CHECK ;IFS. check IFS share,may create share ;AN000;
160 ; JC nomore ;IFS. share violation ;AN000;
161 ;Extended open hooks
162
163 TEST [EXTOPEN_ON],ext_open_on ;FT. from extnded open ;AN000;
164 JNZ IFS_extopen ;FT. isuue extended open ;AN000;
165 ;Extended open hooks
166
167 IF NOT Installed
168 transfer NET_OPEN
169 ELSE
170 PUSH AX
171 MOV AX,(multNET SHL 8) OR 22
172 INT 2FH
173 POP BX ; clean stack
174 ; JC nomore ;IFS. error ;AN000;
175 update_size: ;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;
181 nomore2:
182 ; CLC
183 nomore:
184 return
185 ENDIF
186
187 LOCAL_OPEN:
188 EnterCrit critDisk
189
190 ; DOS 3.3 FastOPen 6/16/86
191
192 OR [FastOpenFlg],FastOpen_Set+Special_Fill_Set ; only open can
193 invoke GetPath
194
195
196 ; DOS 3.3 FastOPen 6/16/86
197
198 JNC Open_found
199 JNZ bad_path
200 OR CL,CL
201 JZ bad_path
202 OpenFNF:
203 MOV AX,error_file_not_found
204 OpenBadRet:
205 AND BYTE PTR CS:[FastOpenFlg],Fast_yes ;; DOS 3.3
206 STC
207 LeaveCrit critDisk
208 JMP Clear_FastOpen
209
210 bad_path:
211 MOV AX,error_path_not_found
212 JMP OpenBadRet
213
214 open_bad_access:
215 MOV AX,error_access_denied
216 JMP OpenBadRet
217
218 Open_found:
219 JZ Open_Bad_Access ; test for directories
220 OR AH,AH
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
225 JNZ open_bad_access
226 TEST AL,attr_read_only ; check write on read only
227 JZ open_ok
228 ;
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:
233 ;
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.
237 ;
238 SaveReg <DS,SI>
239 LDS SI,[THISSFT]
240 MOV CX,[SI].sf_mode
241 TEST CX,sf_isFCB ; is it FCB?
242 JNZ ResetAccess ; yes, reset the access
243 MOV DL,CL
244 AND DL,sharing_mask
245 CMP DL,sharing_net_FCB ; is it net FCB?
246 JNZ NormalOpen ; no
247 ResetAccess:
248 AND CX,NOT access_mask ; clear access
249 errnz open_for_read
250 ; OR CX,open_for_read ; stick in open_for_read
251 MOV [SI].sf_mode,CX
252 JMP SHORT FillSFT
253 ;
254 ; The SFT is normal. See if the requested access is open_for_read
255 ;
256 NormalOpen:
257 AND CL,access_mask ; remove extras
258 CMP CL,open_for_read ; is it open for read?
259 JZ FillSFT
260 RestoreReg <SI,DS>
261 JMP short open_bad_access
262 ;
263 ; All done, restore registers and fill the SFT.
264 ;
265 FillSFT:
266 RestoreReg <SI,DS>
267 open_ok:
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;
284 NORM1: ;AN000;
285 ; POP AX ;FT. ;AN000;
286 NORM0:
287
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 ;
292 JNC Share_Ok
293 LeaveCrit critDisk
294 JMP Clear_FastOPen
295
296 SHARE_OK:
297 MOV AX,3
298 LES DI,ThisSFT
299 if installed
300 call JShare + 14 * 4
301 else
302 Call ShSU
303 endif
304 ;; DOS 4.00 10/27/86
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;
312 no_fastseek:
313
314 ;; DOS 4.00 10/27/86
315
316 LeaveCrit critDisk
317
318 ;
319 ; Finish SFT initialization for new reference. Set the correct mode.
320 ;
321 ; Inputs:
322 ; ThisSFT points to SFT
323 ;
324 ; Outputs:
325 ; Carry clear
326 ; Registers modified: AX.
327
328 entry SET_SFT_MODE
329 DOSAssume CS,<DS>,"Set_SFT_Mode"
330 ASSUME ES:NOTHING
331
332 LES DI,ThisSFT
333 invoke DEV_OPEN_SFT
334 TEST ES:[DI.sf_mode],sf_isfcb; Clears carry
335 retz ; sf_mode correct
336 MOV AX,[CurrentPDB]
337 MOV ES:[DI.sf_PID],AX ; For FCB sf_PID=PID
338
339 Clear_FastOpen:
340 return ;;;;; DOS 3.3
341
342 EndProc DOS_Open
343
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
349
350 procedure SHARE_ERROR,NEAR
351 DOSAssume CS,<DS>,"Share_Error"
352 ASSUME ES:NOTHING
353 TEST ES:[DI.sf_mode],sf_isfcb
354 JNZ HARD_ERR
355 MOV CL,BYTE PTR ES:[DI.sf_mode]
356 AND CL,sharing_mask
357 CMP CL,sharing_compat
358 JNE NO_HARD_ERR
359 HARD_ERR:
360 invoke SHARE_VIOLATION
361 retnc ; User wants retry
362 NO_HARD_ERR:
363 MOV AX,error_sharing_violation
364 STC
365 return
366
367 EndProc SHARE_ERROR
368
369
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
374
375 procedure DO_SHARE_CHECK,NEAR
376 DOSAssume CS,<DS>,"DO_SHARE__CHECK"
377 ASSUME ES:NOTHING
378 EnterCrit critDisk ; enter critical section
379
380 OPN_RETRY:
381 MOV CX,RetryCount ; Get # tries to do
382 OpenShareRetry:
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
387 Invoke Idle
388 LOOP OpenShareRetry ; One more retry used up
389 OpenShareFail:
390 LES DI,[ThisSft]
391 invoke SHARE_ERROR
392 JNC OPN_RETRY ; User wants more retry
393 Share_Ok2:
394 LeaveCrit critDisk ; leave critical section
395 return
396
397 EndProc DO_SHARE_CHECK
398
399
400 ; Input: ES:DI -> SFT
401 ; Functions: check if IFS owns SHARE
402 ; Output: Zero set, use IFS SHARE
403 ; otherwise, use DOS SHARE
404
405 procedure OWN_SHARE,NEAR ;AN000;
406 DOSAssume CS,<DS>,"OWN_SHARE" ;AN000;
407 ASSUME ES:NOTHING ;AN000;
408
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;
416
417 EndProc OWN_SHARE ;AN000;
418
419
420 ; Input: THISCDS -> CDS
421 ; Functions: check if IFS owns SHARE
422 ; Output: Zero set, use IFS SHARE
423 ; otherwise, use DOS SHARE
424
425 procedure OWN_SHARE2,NEAR ;AN000;
426 DOSAssume CS,<DS>,"OWN_SHARE2" ;AN000;
427 ASSUME ES:NOTHING ;AN000;
428
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;
438 ifs_hasit: ;AN000;
439 return ;IFS. return ;AN000;
440
441 EndProc OWN_SHARE2 ;AN000;
442
443
444 ; Input: ES:DI -> SFT
445 ; Functions: set THISDPB
446 ; Output: none
447
448 procedure SET_THISDPB,NEAR ;AN000;
449 DOSAssume CS,<DS>,"SET_THISDPB" ;AN000;
450 ASSUME ES:NOTHING ;AN000;
451
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;
461
462 EndProc SET_THISDPB ;AN000;
463
464
465 ; Input: ES:DI -> SFT
466 ; Functions: check IFS share
467 ; Output: none
468
469 procedure IFS_SHARE_CHECK,NEAR ;AN000;
470 DOSAssume CS,<DS>,"IFS_SHARE_CHECK" ;AN000;
471 ASSUME ES:NOTHING ;AN000;
472
473
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;
480 IFSSHARE: ;AN000;
481 return ;IFS. return ;AN000;
482
483 EndProc IFS_SHARE_CHECK ;AN000;
484
485 ; Inputs:
486 ; AX is mode
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.
497 ; Function:
498 ; Check this access mode for correctness
499 ; Outputs:
500 ; [open_access] = AL input
501 ; Carry Clear
502 ; Mode is correct
503 ; AX unchanged
504 ; Carry Set
505 ; Mode is bad
506 ; AX = error_invalid_access
507 ; No other registers effected
508
509 procedure Check_Access_AX
510 DOSAssume CS,<DS>,"Check_Access"
511 ASSUME ES:NOTHING
512
513 MOV Open_Access,AL
514 PUSH BX
515 ;
516 ; If sharing, then test for special sharing mode for FCBs
517 ;
518 MOV BL,AL
519 AND BL,sharing_mask
520 CMP fSharing,-1
521 JNZ CheckShareMode ; not through server call, must be ok
522 CMP BL,sharing_NET_FCB
523 JZ CheckAccessMode ; yes, we have an FCB
524 CheckShareMode:
525 CMP BL,40h ; is this a good sharing mode?
526 JA Make_Bad_Access
527 CheckAccessMode:
528 MOV BL,AL
529 AND BL,access_mask
530 CMP BL,2
531 JA Make_Bad_Access
532 POP BX
533 CLC
534 return
535
536 make_bad_access:
537 MOV AX,error_invalid_access
538 POP BX
539 STC
540 return
541
542 EndProc Check_Access_AX
543
544 ; Input: none
545 ; Function: Issue Code Page Mismatched INT 24 Critical Error
546 ; OutPut: AL =0 ignore
547 ; =3 fail
548
549 procedure Code_Page_Mismatched_Error,NEAR ;AN000;
550 DOSAssume CS,<DS>,"Code_Page_Mismatched_Error" ;AN000;
551 ASSUME ES:NOTHING ;AN000;
552
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;
566
567 EndProc Code_Page_Mismatched_Error ;AN000;
568 CODE ENDS
569 END