1 ; SCCSID = @(#)lock.asm 1.1 85/04/10
2 TITLE
LOCK ROUTINES
- Routines for
file locking
11 ; A000 version 4.00 Jan. 1988
15 CODE SEGMENT BYTE PUBLIC 'CODE'
16 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
22 include lock.inc ;AN000;
26 AsmVars
<IBM
, Installed
>
34 i_need RetryCount
,WORD
36 I_Need EXTERR_LOCUS
,BYTE ; Extended Error Locus
38 i_need Lock_Buffer
,DWORD ;AN000; DOS 4.00
39 i_need Temp_Var
,WORD ;AN000; DOS 4.00
41 BREAK <$LockOper
- Lock Calls
>
45 ; MOV BX, Handle (DOS 3.3)
55 ; AX = error_invalid_handle
56 ; = error_invalid_function
57 ; = error_lock_violation
60 ; MOV AX, 5C?? (DOS 4.00)
68 ; ?6 add (lseek EOF/lock/write/unlock)
70 ; MOV CX, count or size
75 ; AX = error_invalid_handle
76 ; = error_invalid_function
77 ; = error_lock_violation
79 procedure $LockOper
,NEAR
80 ASSUME
DS:NOTHING
,ES:NOTHING
81 ; MOV BP,AX ;MS. BP=AX ;AN000;
82 ; AND BP,7FH ;MS. clear bit 7 ;AN000;
83 ; CMP BP,Lock_add ;MS. supported function ? ;AN000;
84 ; JA lock_bad_func ;MS. no, ;AN000;
86 CMP AL,1 ;AN000;;MS. no,
87 JA lock_bad_func
;AN000;;MS. no,
89 PUSH DI ; Save LengthLow
90 invoke SFFromHandle
; ES:DI -> SFT
91 JNC lock_do
; have valid handle
93 error error_invalid_handle
95 MOV EXTERR_LOCUS
,errLoc_Unk
; Extended Error Locus
96 error error_invalid_function
98 ; Align_buffer call has been deleted, since it corrupts the DTA (6/5/88) P5013
101 ; PUSH AX ;AN000;;MS. save ax
102 ; PUSH BX ;AN000;;MS. save handle
103 ; MOV [Temp_Var],DX ;AN000;;MS. save DX
104 ; invoke Align_Buffer ;AN000;;MS. align ds:dx and set DMAADD
105 ; POP BX ;AN000;;MS. restore handle
106 ; POP AX ;AN000;;MS. save ax
108 ; CMP BP,Unlock_all ;AN000;;MS. old function 0 or 1 ?
109 ; JA chk_lock_mul ;AN000;;MS. no, new function
110 ; TEST AL,80H ;AN000;;MS. 80H bit on ?
111 ; JZ old_33 ;AN000;;MS. no, old DOS 3.3 interface
112 ; MOV CX,1 ;AN000;;MS. adjust for new interface
113 ; ADD BP,2 ;AN000;;MS.
114 ; JMP SHORT chk_lock_mul ;AN000;;MS.
116 MOV BX,AX ;AN000;;MS. save AX
118 ;; MOV DX,[Temp_Var] ;AN000;;MS. retore DX (P5013) 6/5/88
120 MOV BP, OFFSET DOSGROUP
:Lock_Buffer
;AN000;;MS. get DOS LOCK buffer
121 MOV WORD PTR [BP.Lock_position
],DX ;AN000;;MS. set low offset
122 MOV WORD PTR [BP.Lock_position
+2],CX;AN000;;MS. set high offset
123 POP CX ;AN000;;MS. get low length
124 MOV WORD PTR [BP.Lock_length
],CX ;AN000;;MS. set low length
125 MOV WORD PTR [BP.Lock_length
+2],SI ;AN000;;MS. set high length
126 MOV CX,1 ;AN000;;MS. one range
128 POP DS ;AN000;;MS. DS:DX points to
129 MOV DX,BP ;AN000;;MS. Lock_Buffer
130 TEST AL,Unlock_all
;AN000;;MS. function 1
131 JNZ DOS_Unlock
;AN000;;MS. yes
132 JMP DOS_Lock
;AN000;;MS. function 0
133 ;;chk_lock_mul: ;AN000;
134 ; POP SI ;AN000;;MS. pop low length
135 ; TEST ES:[DI.sf_flags],sf_isnet ;AN000;;MS. net handle?
136 ; JZ LOCAL_DOS_LOCK ;AN000;;MS. no
137 ; invoke OWN_SHARE ;AN000;;MS. IFS owns share ?
138 ; JNZ LOCAL_DOS_LOCK ;AN000;;MS. no
139 ; MOV BX,AX ;AN000;;MS. BX=AX
140 ; CallInstall NET_XLock,multNet,10 ;AN000;;MS. issue Net Extended Lock
141 ; MOV [Temp_Var],CX ;AN000;;MS. cx= retuened from IFS
142 ; JMP ValChk ;AN000;;MS. check return
143 ;LOCAL_DOS_LOCK: ;AN000;
144 ; CMP BP,Lock_mul_range ;AN000;;MS. lock mul range?
145 ; JNZ unmul ;AN000;;MS. lock mul range?
146 ; JMP LOCAL_LOCK ;AN000;;MS. yes
148 ; CMP BP,Unlock_mul_range ;AN000;;MS. unlock mul range?
149 ; JZ LOCAL_UNLOCK ;AN000;;MS. yes
150 ; CMP BP,Lock_read ;AN000;;MS. lock read?
151 ; JNZ chk_write_unlock ;AN000;;MS. no
152 ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer
153 ; CALL Set_Lock ;AN000;;MS. set the lock
154 ; JC lockerror ;AN000;;MS. error
155 ; invoke $READ ;AN000;;MS. do read
156 ; JC lockerror ;AN000;;MS. error
158 ; transfer SYS_RET_OK ;AN000;;MS. return
159 ;chk_write_unlock: ;AN000;
160 ; CMP BP,Write_unlock ;AN000;;MS. write unlock ?
161 ; JNZ Lock_addf ;AN000;;MS. no
162 ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer
163 ;WriteUnlock: ;AN000;
164 ; PUSH AX ;AN000;;MS. save AX for unlock
165 ; invoke $WRITE ;AN000;;MS. do write
166 ; MOV [Temp_Var],AX ;AN000;;MS. save number of bytes writ
167 ; POP AX ;AN000;;MS. restore AX
168 ; JC lockerror ;AN000;;MS. error
169 ; MOV CX,1 ;AN000;;MS. one range unlock
170 ; PUSH CS ;AN000;;MS.
171 ; POP DS ;AN000;;MS. DS:DX points to
172 ; MOV DX,OFFSET DOSGROUP:Lock_Buffer ;AN000;;MS. Lock_BUffer
173 ; JMP LOCAL_UNLOCK ;AN000;;MS. do unlock
175 ; MOV SI,WORD PTR ES:[DI.SF_Size] ;AN000;;MS. must be lock add
176 ; MOV WORD PTR ES:[DI.SF_Position],SI ;AN000;;MS. set file position to
177 ; MOV SI,WORD PTR ES:[DI.SF_Size+2] ;AN000;;MS. EOF
178 ; MOV WORD PTR ES:[DI.SF_Position+2],SI;AN000;;MS.
179 ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer
180 ; CALL Set_Lock ;AN000;;MS. set the lock
181 ; JC lockerror ;AN000;;MS. error
182 ; JMP WriteUnlock ;AN000;;MS. do write unlock
185 TEST ES:[DI.sf_flags
],sf_isnet
187 ;; invoke OWN_SHARE ;AN000;;MS. IFS owns share ?
188 ;; JNZ LOCAL_UNLOCK ;AN000;;MS. no
190 CallInstall Net_Xlock
,multNet
,10
203 MOV AX,[Temp_VAR
] ;AN000;;MS. AX= number of bytes
206 TEST ES:[DI.sf_flags
],sf_isnet
208 ;; invoke OWN_SHARE ;AN000;;MS. IFS owns share ?
209 ;; JNZ LOCAL_LOCK ;AN000;;MS. no
210 CallInstall NET_XLock
,multNet
,10
225 ; BP = Lock_Buffer addr
230 ; carry clear ,Lock is set
232 ; carry set Lock is not set
235 ; procedure Set_Lock,NEAR ;AN000;
236 ;ASSUME DS:NOTHING,ES:NOTHING ;AN000;
238 ; PUSH DS ;MS. save regs ;AN000;
239 ; PUSH DX ;MS. ;AN000;
240 ; PUSH CX ;MS. ;AN000;
242 ; PUSH CS ;MS. ;AN000;
243 ; POP DS ;MS. DS:DX poits to Lock_Buffer ;AN000;
244 ; MOV DX,BP ;MS. ;AN000;
245 ; PUSH BX ;MS. save handle ;AN000;
246 ; PUSH AX ;MS. save functions ;AN000;
247 ; MOV CX,1 ;MS. set one lock ;AN000;
248 ;if installed ;AN000;
249 ; Call JShare + 6 * 4 ;MS. call share set block ;AN000;
251 ; Call Set_Block ;MS. ;AN000;
253 ; POP AX ;MS. restore regs ;AN000;
254 ; POP BX ;MS. ;AN000;
255 ; POP CX ;MS. ;AN000;
256 ; POP DX ;MS. ;AN000;
257 ; POP DS ;MS. ;AN000;
258 ; return ;MS. ;AN000;
260 ;EndProc Set_Lock ;AN000;
262 BREAK <Set_Lock_Buffer
>
265 ; ES:DI = addr of SFT
268 ; set up the lock buffer
270 ; Lock_Buffer is filled with position and lock length
271 ; BP = Lock_Buffer addr
274 ; procedure Set_Lock_Buffer,NEAR
275 ;ASSUME DS:NOTHING,ES:NOTHING
277 ; MOV BP, OFFSET DOSGROUP:Lock_Buffer ;MS. move file position ;AN000;
278 ; MOV SI,WORD PTR ES:[DI.sf_position] ;MS. to DOS lock_buffer ;AN000;
279 ; MOV WORD PTR [BP.Lock_position],SI ;MS. ;AN000;
280 ; MOV SI,WORD PTR ES:[DI.sf_position+2] ;MS. ;AN000;
281 ; MOV WORD PTR [BP.Lock_position+2],SI ;MS. ;AN000;
282 ; MOV WORD PTR [BP.Lock_length],CX ;MS. move cx to lock_buffer ;AN000;
283 ; MOV WORD PTR [BP.Lock_length+2],0 ;MS. ;AN000;
284 ; return ;MS. ;AN000;
286 ;EndProc Set_Lock_Buffer
293 ; Check for lock violations on local I/O
294 ; Retries are attempted with sleeps in between
299 ; A lock violation detected
300 ; Outputs of SETUP preserved
302 procedure LOCK_CHECK
,NEAR
303 DOSAssume
CS,<DS>,"Lock_Check"
306 MOV BX,RetryCount
; Number retries
308 SaveReg
<BX,AX> ; MS. save regs ;AN000;
314 RestoreReg
<AX,BX> ; MS. restrore regs ;AN000;
315 retnc
; There are no locks
316 Invoke Idle
; wait a while
317 DEC BX ; remember a retry
318 JNZ LockRetry
; more retries left...
325 ; [READOP] indicates whether error on read or write
327 ; Handle Lock violation on compatibility (FCB) mode SFTs
329 ; Carry set if user says FAIL, causes error_lock_violation
330 ; Carry clear if user wants a retry
332 ; DS, ES, DI, CX preserved, others destroyed
334 procedure LOCK_VIOLATION
,NEAR
335 DOSAssume
CS,<DS>,"Lock_Violation"
342 MOV AX,error_lock_violation
343 MOV [ALLOWED
],allowed_FAIL
+ allowed_RETRY
345 MOV DI,1 ; Fake some registers
347 MOV DX,ES:[BP.dpb_first_sector
]
354 retz
; 1 = retry, carry clear
358 EndProc LOCK_VIOLATION
362 ; do a retz to return error
364 Procedure CheckShare
,NEAR
365 ASSUME
CS:DOSGROUP
,ES:NOTHING
,DS:NOTHING
,SS:NOTHING