1 ; SCCSID = @(#)util.asm 1.1 85/04/10
2 TITLE UTIL
- Handle utilities
5 ; Handle related utilities for MSDOS 2.X.
7 ; pJFNFromHandle written
13 ; Modification history:
15 ; Created: MZ 1 April 1983
20 ; get the appropriate segment definitions
24 CODE SEGMENT BYTE PUBLIC 'CODE'
25 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
34 I_need CurrentPDB
,WORD ; current process data block location
35 I_need SFT_Addr
,DWORD ; pointer to beginning of table
36 I_Need PROC_ID
,WORD ; current process ID
37 I_Need USER_ID
,WORD ; current user ID
44 BREAK <pJFNFromHandle
- return pointer to JFN table
entry>
47 ; pJFNFromHandle - Given a handle, return the pointer to the JFN location
48 ; in the user's data space
53 ; ES:DI point to the handle spot
55 ; If no error, ES:DI, else AX,ES
57 ; This routine is called from $CREATE_PROCESS_DATA_BLOCK which is called
58 ; at DOSINIT time with SS NOT DOSGROUP
59 procedure pJFNFromHandle
,NEAR
60 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
61 MOV ES,[CurrentPDB
] ; get user process data block
62 CMP BX,ES:[PDB_JFN_Length
] ; is handle greater than allocated
63 JB JFNAdd
; no, get offset
64 fmt TypAccess
,LevSFN
,<"$p: Illegal JFN %x\n">,<BX>
65 MOV AL,error_invalid_handle
; appropriate error
69 JFNAdd: LES DI,ES:[PDB_JFN_Pointer
] ; get pointer to beginning of table
70 ADD DI,BX ; add in offset
74 EndProc pJFNFromHandle
76 BREAK <SFFromHandle
- return pointer
(or error
) to SF
entry from handle
>
79 ; SFFromHandle - Given a handle, get JFN and then index into SF table
81 ; Input: BX has handle
85 ; ES:DI has pointer to SF entry
86 ; Registers modified: If error, AX,ES, else ES:DI
88 ; This routine is called from $CREATE_PROCESS_DATA_BLOCK which is called
89 ; at DOSINIT time with SS NOT DOSGROUP
90 procedure SFFromHandle
,NEAR
91 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
92 CALL pJFNFromHandle
; get jfn pointer
93 retc
; return if error
94 CMP BYTE PTR ES:[DI],-1 ; unused handle
95 JNZ GetSF
; nope, suck out SF
96 fmt TypAccess
,LevSFN
,<"$p: Illegal SFN $x:$x\n">,<ES,DI>
97 MOV AL,error_invalid_handle
; appropriate error
98 jump ReturnCarry
; signal it
100 SaveReg
<BX> ; save handle
101 MOV BL,BYTE PTR ES:[DI] ; get SFN
102 XOR BH,BH ; ignore upper half
103 CALL SFFromSFN
; get real sf spot
104 RestoreReg
<BX> ; restore
108 BREAK <SFFromSFN
- index
into SF table for SFN
>
111 ; SFFromSFN - index into SF tables for SFN.
113 ; Input: BX has SF index
114 ; Output: ES:DI points to SF entry
115 ; Registers modified: ES:DI, BX only
117 ; This routine is called from SFFromHandle which is called
118 ; at DOSINIT time with SS NOT DOSGROUP
119 procedure SFFromSFN
,NEAR
120 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
121 LES DI,[SFT_Addr
] ; get pointer to beginning of table
123 CMP BX,ES:[DI].SFCount
; is handle in this table?
124 JB GetOffset
; yes, go grab it
125 SUB BX,ES:[DI].SFCount
126 LES DI,ES:[DI].SFLink
; get next table segment
127 CMP DI,-1 ; end of tables?
128 JNZ ScanLoop
; no, try again
130 JMP SHORT Restore ; go restore
132 SaveReg
<AX> ; save AX
133 MOV AX,SIZE SF_Entry
; put it in a nice place
135 ADD DI,AX ; offset by size
136 RestoreReg
<AX> ; get world back
137 ADD DI,SFTable
; offset into structure
143 BREAK <JFNFree
- return a jfn pointer
if one is free
>
146 ; JFNFree - scan through the JFN table and return a pointer to a free slot
150 ; AX has error code, BX,ES,DI garbage
152 ; BX has new handle, ES:DI is pointer to JFN slot
153 ; Registers modified: As above only.
154 procedure JFNFree
,NEAR
155 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:DOSGROUP
156 XOR BX,BX ; try starting low
158 CALL pJFNFromHandle
; get the appropriate handle
159 JC JFNNone
; no more handles
160 CMP BYTE PTR ES:[DI],-1 ; free?
161 JZ JFNFound
; yes, carry is clear
162 INC BX ; no, next handle
163 JMP JFNScan
; and try again
165 MOV AL,error_too_many_open_files
170 BREAK <SFNFree
- find a free SFN
>
173 ; SFNFree - scan through the sf table looking for free entries
175 ; Outputs: Carry Set - AX has error code, BX destroyed
176 ; Carry Clear - BX has SFN
177 ; ES:DI - pointer to SFT
178 ; SFT_ref_count is set to 1
179 ; Registers modified: none
181 Procedure SFNFree
,NEAR
182 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:DOSGROUP
183 XOR BX,BX ; start at beginning
185 SaveReg
<BX> ; Next call zaps BX
186 CALL SFFromSFN
; get the potential handle
188 JNC SFNCheck
; no carry, check to see if its free
189 MOV AL,error_too_many_open_files
; appropriate error
192 CMP ES:[DI.sf_Ref_Count
],0 ; free?
194 JZ SFNGot
; yep, got return him
200 CMP ES:[DI.sf_ref_count
],sf_busy
201 JNZ SFNNext
; not marked busy...
202 fmt TypAccess
,LevSFN
,<"$p: SFT $x:$x($x)is busy, owner $x:$x\n">,<ES,DI,BX,ES:[DI].sf_UID
,ES:[DI].sf_pid
>
205 CMP ES:[DI.sf_UID
],BX
208 CMP ES:[DI.sf_PID
],BX
211 fmt TypAccess
,LevSFN
,<"$p: SFT unusable\n">
214 INC BX ; no, try next sf number
215 JMP SFNFreeLoop
; and go until it fails
220 fmt TypAccess
,LevSFN
,<"$p: SFT $x:$x($x) marked busy\n">,<ES,DI,BX>
221 MOV ES:[DI.sf_ref_count
],sf_busy
; make sure that this is allocated
223 MOV ES:[DI.sf_UID
],BX
225 MOV ES:[DI.sf_PID
],BX