1 | ;
|
---|
2 | ; FILEIO.ASM -- Handle files and file handles
|
---|
3 | ;
|
---|
4 | ; Copyright (c) 1991-1996 by Eberhard Mattes
|
---|
5 | ;
|
---|
6 | ; This file is part of emx.
|
---|
7 | ;
|
---|
8 | ; emx is free software; you can redistribute it and/or modify it
|
---|
9 | ; under the terms of the GNU General Public License as published by
|
---|
10 | ; the Free Software Foundation; either version 2, or (at your option)
|
---|
11 | ; any later version.
|
---|
12 | ;
|
---|
13 | ; emx is distributed in the hope that it will be useful,
|
---|
14 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
16 | ; GNU General Public License for more details.
|
---|
17 | ;
|
---|
18 | ; You should have received a copy of the GNU General Public License
|
---|
19 | ; along with emx; see the file COPYING. If not, write to
|
---|
20 | ; the Free Software Foundation, 59 Temple Place - Suite 330,
|
---|
21 | ; Boston, MA 02111-1307, USA.
|
---|
22 | ;
|
---|
23 | ; See emx.asm for a special exception.
|
---|
24 | ;
|
---|
25 |
|
---|
26 | INCLUDE EMX.INC
|
---|
27 | INCLUDE SIGNAL.INC
|
---|
28 | INCLUDE PROCESS.INC
|
---|
29 | INCLUDE SWAPPER.INC
|
---|
30 | INCLUDE ERRORS.INC
|
---|
31 | INCLUDE OPTIONS.INC
|
---|
32 | INCLUDE OPRINT.INC
|
---|
33 | INCLUDE PMINT.INC
|
---|
34 | INCLUDE UTILS.INC
|
---|
35 |
|
---|
36 | TOTAL_FILES = 128
|
---|
37 |
|
---|
38 | SV_DATA SEGMENT
|
---|
39 |
|
---|
40 | ;
|
---|
41 | ; For each DOS file handle, this array contains the number of times
|
---|
42 | ; the handle is referenced.
|
---|
43 | ;
|
---|
44 | DOS_REF_COUNT DW TOTAL_FILES DUP (?)
|
---|
45 |
|
---|
46 | $CHECK_HANDLES DB "Internal error: wrong handle reference count", 0
|
---|
47 |
|
---|
48 | $DIR_DEV BYTE "DEV", 0
|
---|
49 | $DIR_PIPE BYTE "PIPE", 0
|
---|
50 |
|
---|
51 | SV_DATA ENDS
|
---|
52 |
|
---|
53 |
|
---|
54 | SV_CODE SEGMENT
|
---|
55 |
|
---|
56 | ASSUME CS:SV_CODE, DS:NOTHING
|
---|
57 |
|
---|
58 | ;
|
---|
59 | ; Implementation of __dup()
|
---|
60 | ;
|
---|
61 | ; In: AX File handle
|
---|
62 | ; BX Pointer to process table entry
|
---|
63 | ;
|
---|
64 | ; Out: AX errno if CY set
|
---|
65 | ; AX File handle if CY clear
|
---|
66 | ; CY Error
|
---|
67 | ;
|
---|
68 | ; Find an available file handle, then use common code for
|
---|
69 | ; DO_DUP and DO_DUP2.
|
---|
70 | ;
|
---|
71 | TALIGN 4
|
---|
72 | ASSUME DS:SV_DATA
|
---|
73 | ASSUME BX:PTR PROCESS
|
---|
74 | DO_DUP PROC NEAR
|
---|
75 | ;
|
---|
76 | ; Check the file handle
|
---|
77 | ;
|
---|
78 | CMP AX, MAX_FILES
|
---|
79 | JAE SHORT DUP_EBADF
|
---|
80 | MOV SI, AX
|
---|
81 | SHL SI, 1
|
---|
82 | CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE
|
---|
83 | JE SHORT DUP_EBADF
|
---|
84 | ;
|
---|
85 | ; Find an available file handle
|
---|
86 | ;
|
---|
87 | MOV SI, 0
|
---|
88 | MOV CX, 0
|
---|
89 | DUP_LOOP: CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE
|
---|
90 | JE DUP_FOUND
|
---|
91 | ADD SI, 2
|
---|
92 | INC CX
|
---|
93 | CMP CX, MAX_FILES
|
---|
94 | JB SHORT DUP_LOOP
|
---|
95 | MOV AX, EMFILE ; Too many open files
|
---|
96 | STC
|
---|
97 | RET
|
---|
98 |
|
---|
99 | DUP_EBADF: MOV AX, EBADF
|
---|
100 | STC
|
---|
101 | RET
|
---|
102 |
|
---|
103 | ;
|
---|
104 | ; File handle found, call common code
|
---|
105 | ;
|
---|
106 | DUP_FOUND: CALL DUP_COMMON
|
---|
107 | CLC
|
---|
108 | RET
|
---|
109 | ASSUME BX:NOTHING
|
---|
110 | DO_DUP ENDP
|
---|
111 |
|
---|
112 |
|
---|
113 | ;
|
---|
114 | ; Implementation of __dup2()
|
---|
115 | ;
|
---|
116 | ; In: AX Source handle
|
---|
117 | ; CX Target handle
|
---|
118 | ; BX Pointer to process table entry
|
---|
119 | ;
|
---|
120 | ; Out: AX errno if CY set
|
---|
121 | ; AX File handle if CY clear
|
---|
122 | ;
|
---|
123 | ; Check the file handles, then use common code for
|
---|
124 | ; DO_DUP and DO_DUP2.
|
---|
125 | ;
|
---|
126 | TALIGN 4
|
---|
127 | ASSUME DS:SV_DATA
|
---|
128 | ASSUME BX:PTR PROCESS
|
---|
129 | DO_DUP2 PROC NEAR
|
---|
130 | ;
|
---|
131 | ; Check the source file handle
|
---|
132 | ;
|
---|
133 | CMP AX, MAX_FILES
|
---|
134 | JAE SHORT DUP2_EBADF
|
---|
135 | MOV SI, AX
|
---|
136 | SHL SI, 1
|
---|
137 | CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE
|
---|
138 | JE SHORT DUP2_EBADF
|
---|
139 | ;
|
---|
140 | ; Do nothing if the two handles are identical
|
---|
141 | ;
|
---|
142 | CMP AX, CX ; Handles identical?
|
---|
143 | JE SHORT DUP2_OK ; Yes -> return the handle
|
---|
144 | ;
|
---|
145 | ; Check the target file handle. Close the target handle if it is open
|
---|
146 | ;
|
---|
147 | CMP CX, MAX_FILES
|
---|
148 | JAE SHORT DUP2_EBADF
|
---|
149 | MOV SI, CX
|
---|
150 | SHL SI, 1
|
---|
151 | CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE
|
---|
152 | JE SHORT DUP2_CONT
|
---|
153 | PUSH AX
|
---|
154 | PUSH CX
|
---|
155 | MOV AX, CX
|
---|
156 | CALL DO_CLOSE
|
---|
157 | POP CX
|
---|
158 | POP DX
|
---|
159 | JC SHORT DUP2_RET ; Error
|
---|
160 | MOV AX, DX
|
---|
161 | ;
|
---|
162 | ; Call common code
|
---|
163 | ;
|
---|
164 | DUP2_CONT: CALL DUP_COMMON
|
---|
165 | DUP2_OK: CLC
|
---|
166 | DUP2_RET: RET
|
---|
167 |
|
---|
168 | DUP2_EBADF: MOV AX, EBADF
|
---|
169 | STC
|
---|
170 | RET
|
---|
171 |
|
---|
172 | ASSUME BX:NOTHING
|
---|
173 | DO_DUP2 ENDP
|
---|
174 |
|
---|
175 |
|
---|
176 | ;
|
---|
177 | ; Common code for DO_DUP and DO_DUP2, both handles have been checked,
|
---|
178 | ; no error is possible. The target handle is available.
|
---|
179 | ;
|
---|
180 | ; In: AX Source handle
|
---|
181 | ; CX Target handle
|
---|
182 | ; BX Pointer to process table entry
|
---|
183 | ;
|
---|
184 | ; Out: AX File handle
|
---|
185 | ;
|
---|
186 | TALIGN 4
|
---|
187 | ASSUME DS:SV_DATA
|
---|
188 | ASSUME BX:PTR PROCESS
|
---|
189 | DUP_COMMON PROC NEAR
|
---|
190 | MOV SI, AX
|
---|
191 | SHL SI, 1
|
---|
192 | MOV AX, [BX].P_HFLAGS[SI]
|
---|
193 | MOV DX, [BX].P_HANDLES[SI]
|
---|
194 | MOV SI, CX
|
---|
195 | SHL SI, 1
|
---|
196 | MOV [BX].P_HANDLES[SI], DX
|
---|
197 | AND AX, NOT HF_NOINHERIT ; Clear FD_CLOEXEC
|
---|
198 | MOV [BX].P_HFLAGS[SI], AX
|
---|
199 | MOV SI, DX
|
---|
200 | SHL SI, 1
|
---|
201 | INC DOS_REF_COUNT[SI]
|
---|
202 | MOV AX, CX
|
---|
203 | CALL MAYBE_CHECK_HANDLES
|
---|
204 | RET
|
---|
205 | ASSUME BX:NOTHING
|
---|
206 | DUP_COMMON ENDP
|
---|
207 |
|
---|
208 | ;
|
---|
209 | ; Close a file handle
|
---|
210 | ;
|
---|
211 | ; In: AX File handle
|
---|
212 | ; BX Pointer to process table entry
|
---|
213 | ;
|
---|
214 | ; Out: AX errno if CY set
|
---|
215 | ; CY Error
|
---|
216 | ;
|
---|
217 | TALIGN 4
|
---|
218 | ASSUME DS:SV_DATA
|
---|
219 | ASSUME BX:PTR PROCESS
|
---|
220 | DO_CLOSE PROC NEAR
|
---|
221 | PUSH DX
|
---|
222 | PUSH SI
|
---|
223 | CMP AX, MAX_FILES
|
---|
224 | JAE SHORT CLOSE_EBADF
|
---|
225 | MOV SI, AX
|
---|
226 | SHL SI, 1
|
---|
227 | MOV DX, [BX].P_HANDLES[SI]
|
---|
228 | CMP DX, NO_FILE_HANDLE
|
---|
229 | JE SHORT CLOSE_EBADF
|
---|
230 | MOV [BX].P_HANDLES[SI], NO_FILE_HANDLE
|
---|
231 | MOV [BX].P_HFLAGS[SI], 0
|
---|
232 | MOV SI, DX
|
---|
233 | SHL SI, 1
|
---|
234 | ;
|
---|
235 | ; The reference count should not be zero here. Handle that case, anyway.
|
---|
236 | ;
|
---|
237 | CMP DOS_REF_COUNT[SI], 0
|
---|
238 | JE SHORT CLOSE_CLOSE
|
---|
239 | DEC DOS_REF_COUNT[SI]
|
---|
240 | JNZ SHORT CLOSE_OK
|
---|
241 | ;
|
---|
242 | ; Close the DOS file handle
|
---|
243 | ;
|
---|
244 | CLOSE_CLOSE: PUSH BX
|
---|
245 | MOV BX, DX
|
---|
246 | MOV AH, 3EH
|
---|
247 | PUSH PROCESS_PTR
|
---|
248 | MOV PROCESS_PTR, NO_PROCESS
|
---|
249 | INT 21H
|
---|
250 | POP PROCESS_PTR
|
---|
251 | POP BX
|
---|
252 | JMP SHORT CLOSE_RET
|
---|
253 |
|
---|
254 | CLOSE_OK: CALL MAYBE_CHECK_HANDLES
|
---|
255 | XOR AX, AX
|
---|
256 | CLOSE_RET: POP SI
|
---|
257 | POP DX
|
---|
258 | RET
|
---|
259 |
|
---|
260 | CLOSE_EBADF: MOV AX, EBADF
|
---|
261 | STC
|
---|
262 | JMP SHORT CLOSE_RET
|
---|
263 | ASSUME BX:NOTHING
|
---|
264 | DO_CLOSE ENDP
|
---|
265 |
|
---|
266 |
|
---|
267 | ;
|
---|
268 | ; Translate file handle (process PROCESS_PTR) to DOS file handle
|
---|
269 | ;
|
---|
270 | ; In: AX File handle
|
---|
271 | ; PROCESS_PTR
|
---|
272 | ;
|
---|
273 | ; Out: AX DOS file handle (NO_FILE_HANDLE if file not open)
|
---|
274 | ; CY Not a valid handle
|
---|
275 | ;
|
---|
276 | TALIGN 4
|
---|
277 | ASSUME DS:SV_DATA
|
---|
278 | GET_HANDLE PROC NEAR
|
---|
279 | CMP AX, MAX_FILES
|
---|
280 | JAE SHORT GET_HANDLE_ERR
|
---|
281 | PUSH BX
|
---|
282 | PUSH SI
|
---|
283 | MOV SI, AX
|
---|
284 | SHL SI, 1
|
---|
285 | MOV BX, PROCESS_PTR
|
---|
286 | MOV AX, (PROCESS PTR [BX]).P_HANDLES[SI]
|
---|
287 | POP SI
|
---|
288 | POP BX
|
---|
289 | CLC
|
---|
290 | RET
|
---|
291 | GET_HANDLE_ERR: MOV AX, NO_FILE_HANDLE
|
---|
292 | STC
|
---|
293 | RET
|
---|
294 | GET_HANDLE ENDP
|
---|
295 |
|
---|
296 |
|
---|
297 | ;
|
---|
298 | ; Put new handle into handle translation table
|
---|
299 | ;
|
---|
300 | ; In: AX DOS file handle
|
---|
301 | ; PROCESS_PTR
|
---|
302 | ;
|
---|
303 | ; Out: CY No empty slot found
|
---|
304 | ; EAX emx file handle
|
---|
305 | ;
|
---|
306 | ; Note:
|
---|
307 | ; When called with AX=NO_FILE_HANDLE, this function just looks for an
|
---|
308 | ; empty slot, but does not use that slot.
|
---|
309 | ;
|
---|
310 |
|
---|
311 | TALIGN 4
|
---|
312 | ASSUME DS:SV_DATA
|
---|
313 | NEW_HANDLE PROC NEAR
|
---|
314 | PUSH BX
|
---|
315 | PUSH DX
|
---|
316 | PUSH SI
|
---|
317 | MOV BX, PROCESS_PTR
|
---|
318 | MOV SI, 0
|
---|
319 | MOV DX, 0
|
---|
320 | ASSUME BX:PTR PROCESS
|
---|
321 | TALIGN 4
|
---|
322 | NH_LOOP: CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE ; Empty slot?
|
---|
323 | JE SHORT NH_FOUND ; Yes -> use it
|
---|
324 | ADD SI, 2 ; Next slot
|
---|
325 | INC DX
|
---|
326 | CMP DX, MAX_FILES
|
---|
327 | JB SHORT NH_LOOP
|
---|
328 | NH_ERROR: STC ; Out of file handles
|
---|
329 | JMP SHORT NH_RET
|
---|
330 |
|
---|
331 | TALIGN 4
|
---|
332 | NH_FOUND: CMP AX, NO_FILE_HANDLE
|
---|
333 | JE SHORT NH_OK
|
---|
334 | CMP AX, TOTAL_FILES
|
---|
335 | JAE SHORT NH_ERROR
|
---|
336 | MOV [BX].P_HANDLES[SI], AX ; Store DOS file handle
|
---|
337 | MOV [BX].P_HFLAGS[SI], 0 ; Clear handle flags
|
---|
338 | MOV SI, AX
|
---|
339 | SHL SI, 1
|
---|
340 | MOV DOS_REF_COUNT[SI], 1
|
---|
341 | NH_OK: MOVZX EAX, DX
|
---|
342 | CALL MAYBE_CHECK_HANDLES
|
---|
343 | CLC
|
---|
344 | NH_RET: POP SI
|
---|
345 | POP DX
|
---|
346 | POP BX
|
---|
347 | RET
|
---|
348 | ASSUME BX:NOTHING
|
---|
349 | NEW_HANDLE ENDP
|
---|
350 |
|
---|
351 | ;
|
---|
352 | ; Remap file handles to make the DOS handle identical to the user process'
|
---|
353 | ; handle.
|
---|
354 | ;
|
---|
355 | ; In: AX File handle
|
---|
356 | ; PROCESS_PTR
|
---|
357 | ;
|
---|
358 | ; Out: AX errno if CY is set
|
---|
359 | ; CY Error
|
---|
360 | ;
|
---|
361 | ; TODO: Handle HF_NOINHERIT.
|
---|
362 | ;
|
---|
363 | MH_HANDLE EQU (WORD PTR [BP-1*2])
|
---|
364 | MH_RELOC EQU (WORD PTR [BP-2*2])
|
---|
365 | MH_DOSHANDLE EQu (WORD PTR [BP-3*2])
|
---|
366 |
|
---|
367 | TALIGN 4
|
---|
368 | ASSUME DS:SV_DATA
|
---|
369 | MAP_HANDLE PROC NEAR
|
---|
370 | PUSH BX
|
---|
371 | PUSH CX
|
---|
372 | PUSH DX
|
---|
373 | PUSH SI
|
---|
374 | PUSH BP
|
---|
375 | MOV BP, SP
|
---|
376 | SUB SP, 3 * 2
|
---|
377 | MOV MH_HANDLE, AX
|
---|
378 | MOV BX, PROCESS_PTR
|
---|
379 | ASSUME BX:PTR PROCESS
|
---|
380 | MOV SI, AX
|
---|
381 | SHL SI, 1
|
---|
382 | MOV DX, [BX].P_HANDLES[SI] ; Fetch curent DOS handle
|
---|
383 | CMP AX, DX ; Mapping required?
|
---|
384 | JE MH_OK ; No -> done
|
---|
385 | MOV MH_DOSHANDLE, DX
|
---|
386 | ;
|
---|
387 | ; Check whether we have to relocate the DOS handle. It must be relocated
|
---|
388 | ; if it is used.
|
---|
389 | ;
|
---|
390 | CMP DOS_REF_COUNT[SI], 0 ; DOS handle used at all?
|
---|
391 | JNE SHORT MH_RELOCATE ; Yes -> relocate
|
---|
392 | CMP AX, SWAP_HANDLE ; Used for swap file?
|
---|
393 | JE SHORT MH_RELOCATE ; Yes -> relocate
|
---|
394 | ;
|
---|
395 | ; Check whether the handle is used for an executable file
|
---|
396 | ;
|
---|
397 | LEA BX, PROCESS_TABLE
|
---|
398 | MOV CX, MAX_PROCESSES
|
---|
399 | MH_EXEC_LOOP: CMP AX, [BX].P_EXEC_HANDLE
|
---|
400 | JE SHORT MH_RELOCATE
|
---|
401 | ADD BX, SIZE PROCESS
|
---|
402 | LOOP MH_EXEC_LOOP
|
---|
403 | JMP SHORT MH_NO_RELOC
|
---|
404 | ;
|
---|
405 | ; Relocate the DOS handle to make it available, updating the translation
|
---|
406 | ; tables of all processes
|
---|
407 | ;
|
---|
408 | MH_RELOCATE: MOV BX, MH_HANDLE
|
---|
409 | ASSUME BX:NOTHING
|
---|
410 | MOV AH, 45H
|
---|
411 | PUSH PROCESS_PTR
|
---|
412 | MOV PROCESS_PTR, NO_PROCESS
|
---|
413 | INT 21H
|
---|
414 | POP PROCESS_PTR
|
---|
415 | JC MH_RET
|
---|
416 | CMP AX, TOTAL_FILES
|
---|
417 | JAE MH_ERROR
|
---|
418 | MOV MH_RELOC, AX ; Relocated handle
|
---|
419 |
|
---|
420 | MOV AH, 3EH ; Close the original handle
|
---|
421 | PUSH PROCESS_PTR
|
---|
422 | MOV PROCESS_PTR, NO_PROCESS
|
---|
423 | INT 21H
|
---|
424 | POP PROCESS_PTR
|
---|
425 | MOV AX, MH_HANDLE
|
---|
426 | MOV DX, MH_RELOC
|
---|
427 | CALL MAP_TRANSLATE
|
---|
428 | ;
|
---|
429 | ; Move the DOS handle previously associated with MH_HANDLE to DOS handle
|
---|
430 | ; MH_HANDLE.
|
---|
431 | ;
|
---|
432 | MH_NO_RELOC: MOV BX, MH_DOSHANDLE ; Is the handle associated
|
---|
433 | CMP BX, NO_FILE_HANDLE ; with a DOS handle?
|
---|
434 | JE SHORT MH_OK ; No -> done (it's closed now)
|
---|
435 | CMP BX, MH_HANDLE ; Same handle?
|
---|
436 | JE SHORT MH_OK ; Yes -> done
|
---|
437 | MOV CX, MH_HANDLE
|
---|
438 | MOV AH, 46H
|
---|
439 | PUSH PROCESS_PTR
|
---|
440 | MOV PROCESS_PTR, NO_PROCESS
|
---|
441 | INT 21H
|
---|
442 | POP PROCESS_PTR
|
---|
443 | JC SHORT MH_RET
|
---|
444 | ;
|
---|
445 | ; Update the P_HANDLES entry for this one handle, leaving the other entries
|
---|
446 | ; of this process and other processes point to the duplicate made above.
|
---|
447 | ; If there are no other entries, we can close the handle.
|
---|
448 | ;
|
---|
449 | MOV BX, PROCESS_PTR
|
---|
450 | ASSUME BX:PTR PROCESS
|
---|
451 | MOV AX, MH_HANDLE
|
---|
452 | MOV SI, AX
|
---|
453 | SHL SI, 1
|
---|
454 | MOV [BX].P_HANDLES[SI], AX
|
---|
455 | ASSUME BX:NOTHING
|
---|
456 | MOV SI, AX
|
---|
457 | SHL SI, 1
|
---|
458 | INC DOS_REF_COUNT[SI]
|
---|
459 | ;
|
---|
460 | ; Update the reference count for the handle and check whether we can close it.
|
---|
461 | ;
|
---|
462 | MOV SI, MH_DOSHANDLE
|
---|
463 | SHL SI, 1
|
---|
464 | CMP DOS_REF_COUNT[SI], 0
|
---|
465 | JE SHORT MH_CLOSE
|
---|
466 | DEC DOS_REF_COUNT[SI]
|
---|
467 | JNZ SHORT MH_OK
|
---|
468 | ;
|
---|
469 | ; The duplicate is no longer referenced, close it now. Note that the
|
---|
470 | ; handle can only be referenced by P_HANDLES.
|
---|
471 | ;
|
---|
472 | MH_CLOSE: MOV BX, MH_DOSHANDLE
|
---|
473 | MOV AH, 3EH
|
---|
474 | PUSH PROCESS_PTR
|
---|
475 | MOV PROCESS_PTR, NO_PROCESS
|
---|
476 | INT 21H
|
---|
477 | POP PROCESS_PTR
|
---|
478 |
|
---|
479 | MH_OK: CALL MAYBE_CHECK_HANDLES
|
---|
480 | XOR AX, AX
|
---|
481 | MH_RET: MOV SP, BP
|
---|
482 | POP BP
|
---|
483 | POP SI
|
---|
484 | POP DX
|
---|
485 | POP CX
|
---|
486 | POP BX
|
---|
487 | ASSUME BX:NOTHING
|
---|
488 | RET
|
---|
489 |
|
---|
490 | MH_ERROR: MOV AX, EMFILE ; ENFILE is not implemented
|
---|
491 | STC
|
---|
492 | JMP SHORT MH_RET
|
---|
493 |
|
---|
494 | MAP_HANDLE ENDP
|
---|
495 |
|
---|
496 |
|
---|
497 | ;
|
---|
498 | ; Update handle translation tables of all processes and other file
|
---|
499 | ; handles. Also update DOS_REF_COUNT.
|
---|
500 | ;
|
---|
501 | ; In: AX Old DOS handle
|
---|
502 | ; DX New DOS handle
|
---|
503 | ;
|
---|
504 | TALIGN 4
|
---|
505 | ASSUME DS:SV_DATA
|
---|
506 | MAP_TRANSLATE PROC NEAR
|
---|
507 | LEA BX, PROCESS_TABLE
|
---|
508 | ASSUME BX:PTR PROCESS
|
---|
509 | MOV DI, 0 ; Number of changes
|
---|
510 | MOV CX, MAX_PROCESSES + 1 ; Include PROC0 (for OCHAR)!
|
---|
511 | MT_LOOP_PROC: MOV SI, 0
|
---|
512 | MT_LOOP_HANDLE: CMP [BX].P_HANDLES[SI], AX
|
---|
513 | JNE SHORT MT_NO_UPDATE_1
|
---|
514 | MOV [BX].P_HANDLES[SI], DX
|
---|
515 | INC DI
|
---|
516 | MT_NO_UPDATE_1: ADD SI, 2
|
---|
517 | CMP SI, 2 * MAX_FILES
|
---|
518 | JB SHORT MT_LOOP_HANDLE
|
---|
519 | CMP AX, [BX].P_EXEC_HANDLE ; Executable file?
|
---|
520 | JNE SHORT MT_NO_UPDATE_2
|
---|
521 | MOV [BX].P_EXEC_HANDLE, DX
|
---|
522 | MT_NO_UPDATE_2: ADD BX, SIZE PROCESS
|
---|
523 | LOOP MT_LOOP_PROC
|
---|
524 | ;
|
---|
525 | ; Update DOS_REF_COUNT
|
---|
526 | ;
|
---|
527 | MOV SI, AX
|
---|
528 | SHL SI, 1
|
---|
529 | SUB DOS_REF_COUNT[SI], DI
|
---|
530 | MOV SI, DX
|
---|
531 | SHL SI, 1
|
---|
532 | ADD DOS_REF_COUNT[SI], DI
|
---|
533 | ;
|
---|
534 | ; Update other file handles
|
---|
535 | ;
|
---|
536 | CMP AX, SWAP_HANDLE ; Swap file?
|
---|
537 | JNE SHORT MT_NO_UPDATE_3
|
---|
538 | MOV SWAP_HANDLE, DX
|
---|
539 | MT_NO_UPDATE_3:
|
---|
540 | RET
|
---|
541 | ASSUME BX:NOTHING
|
---|
542 | MAP_TRANSLATE ENDP
|
---|
543 |
|
---|
544 |
|
---|
545 | ;
|
---|
546 | ; Remap file handles 0 through 2 of the current process to make the
|
---|
547 | ; DOS handles identical to the current process' handle. We don't
|
---|
548 | ; remap all file handles because that would certainly run out of
|
---|
549 | ; DOS handles: To pass closed handles as closed to the child process,
|
---|
550 | ; all used handles must be moved out of 0..MAX_FILES-1, leaving no
|
---|
551 | ; space for non-user handles.
|
---|
552 | ;
|
---|
553 | ; In: PROCESS_PTR
|
---|
554 | ;
|
---|
555 | ; Out: AX errno if CY is set
|
---|
556 | ; CY Error
|
---|
557 | ;
|
---|
558 | TALIGN 4
|
---|
559 | ASSUME DS:SV_DATA
|
---|
560 | MAP_ALL_HANDLES PROC NEAR
|
---|
561 | PUSH BX
|
---|
562 | MOV BX, 0
|
---|
563 | MAH_LOOP: MOV AX, BX
|
---|
564 | CALL MAP_HANDLE
|
---|
565 | JC SHORT MAH_RET
|
---|
566 | INC BX
|
---|
567 | CMP BX, 3
|
---|
568 | JB SHORT MAH_LOOP
|
---|
569 | XOR AX, AX
|
---|
570 | MAH_RET: POP BX
|
---|
571 | RET
|
---|
572 | MAP_ALL_HANDLES ENDP
|
---|
573 |
|
---|
574 |
|
---|
575 | ;
|
---|
576 | ; Duplicate inheritable file handles for a child process
|
---|
577 | ;
|
---|
578 | ; In: SI Pointer to source process table entry (parent)
|
---|
579 | ; DI Pointer to destination process table entry (child)
|
---|
580 | ;
|
---|
581 | ASSUME DS:SV_DATA
|
---|
582 | ASSUME SI:PTR PROCESS
|
---|
583 | ASSUME DI:PTR PROCESS
|
---|
584 | INHERIT_HANDLES PROC NEAR
|
---|
585 | MOV BX, 0
|
---|
586 | IH_LOOP: MOV AX, [SI].P_HANDLES[BX] ; Get DOS handle
|
---|
587 | MOV DX, [SI].P_HFLAGS[BX] ; Get handle flags
|
---|
588 | TEST DX, HF_NOINHERIT ; Inherit?
|
---|
589 | JNZ SHORT IH_NOINHERIT ; No -> skip
|
---|
590 | CMP AX, NO_FILE_HANDLE ; Valid handle?
|
---|
591 | JE SHORT IH_SET ; No -> don't update ref count
|
---|
592 | ;
|
---|
593 | ; Update the reference count
|
---|
594 | ;
|
---|
595 | PUSH BX
|
---|
596 | MOV BX, AX
|
---|
597 | SHL BX, 1
|
---|
598 | INC DOS_REF_COUNT[BX]
|
---|
599 | POP BX
|
---|
600 | ;
|
---|
601 | ; Update the process table entry of the child
|
---|
602 | ;
|
---|
603 | IH_SET: MOV [DI].P_HANDLES[BX], AX
|
---|
604 | MOV [DI].P_HFLAGS[BX], DX
|
---|
605 | JMP SHORT IH_NEXT
|
---|
606 |
|
---|
607 | ;
|
---|
608 | ; Don't inherit the file handle
|
---|
609 | ;
|
---|
610 | IH_NOINHERIT: MOV AX, NO_FILE_HANDLE
|
---|
611 | MOV DX, 0
|
---|
612 | JMP SHORT IH_SET
|
---|
613 |
|
---|
614 | ;
|
---|
615 | ; Process next file handle
|
---|
616 | ;
|
---|
617 | IH_NEXT: ADD BX, 2
|
---|
618 | CMP BX, 2 * MAX_FILES
|
---|
619 | JB IH_LOOP
|
---|
620 | ;
|
---|
621 | ; Redirect stderr to stdout if the -e option is given
|
---|
622 | ;
|
---|
623 | TEST [DI].P_FLAGS, PF_REDIR_STDERR ; Redirect stderr?
|
---|
624 | JE SHORT IH_DONT_REDIR ; No -> skip
|
---|
625 | MOV AX, 1 ; stdout
|
---|
626 | MOV CX, 2 ; stderr
|
---|
627 | MOV BX, DI
|
---|
628 | CALL DO_DUP2
|
---|
629 | IH_DONT_REDIR: RET
|
---|
630 | ASSUME SI:NOTHING
|
---|
631 | ASSUME DI:NOTHING
|
---|
632 | INHERIT_HANDLES ENDP
|
---|
633 |
|
---|
634 | ;
|
---|
635 | ; Close all open file handles of a process
|
---|
636 | ;
|
---|
637 | ; In: BX Pointer to process table entry
|
---|
638 | ;
|
---|
639 | ASSUME DS:SV_DATA
|
---|
640 | ASSUME BX:PTR PROCESS
|
---|
641 | CLOSE_HANDLES PROC NEAR
|
---|
642 | PUSH SI
|
---|
643 | MOV SI, 0
|
---|
644 | CH_LOOP: MOV AX, SI
|
---|
645 | CALL DO_CLOSE
|
---|
646 | INC SI
|
---|
647 | CMP SI, MAX_FILES
|
---|
648 | JB CH_LOOP
|
---|
649 | POP SI
|
---|
650 | RET
|
---|
651 | ASSUME BX:NOTHING
|
---|
652 | CLOSE_HANDLES ENDP
|
---|
653 |
|
---|
654 | ;
|
---|
655 | ; Dump handle tables for debugging
|
---|
656 | ;
|
---|
657 | IF FALSE
|
---|
658 | ASSUME DS:SV_DATA
|
---|
659 | DUMP_HANDLES PROC NEAR
|
---|
660 | PUSHA
|
---|
661 | LEA BX, PROCESS_TABLE
|
---|
662 | ASSUME BX:PTR PROCESS
|
---|
663 | MOV CL, 0
|
---|
664 | DH_LOOP_PROC: MOV SI, 0
|
---|
665 | MOV AL, "0"
|
---|
666 | CMP CL, MAX_PROCESSES
|
---|
667 | JE SHORT DH_PROC0
|
---|
668 | MOV AL, CL
|
---|
669 | ADD AL, "1"
|
---|
670 | DH_PROC0: CALL OCHAR
|
---|
671 | MOV Al, ":"
|
---|
672 | CALL OCHAR
|
---|
673 | MOV AL, " "
|
---|
674 | CALL OCHAR
|
---|
675 | DH_LOOP_HANDLE: MOV AX, [BX].P_HANDLES[SI]
|
---|
676 | CMP AX, NO_FILE_HANDLE
|
---|
677 | JE SHORT DH_NO_HANDLE
|
---|
678 | AAM
|
---|
679 | XCHG AL, AH
|
---|
680 | ADD AL, "0"
|
---|
681 | CALL OCHAR
|
---|
682 | XCHG AL, AH
|
---|
683 | ADD AL, "0"
|
---|
684 | CALL OCHAR
|
---|
685 | JMP SHORT DH_NEXT_HANDLE
|
---|
686 |
|
---|
687 | DH_NO_HANDLE: MOV AL, "-"
|
---|
688 | CALL OCHAR
|
---|
689 | CALL OCHAR
|
---|
690 | DH_NEXT_HANDLE: MOV AL, " "
|
---|
691 | CALL OCHAR
|
---|
692 | ADD SI, 2
|
---|
693 | CMP SI, 2 * 24
|
---|
694 | JB SHORT DH_LOOP_HANDLE
|
---|
695 | CALL OCRLF
|
---|
696 | ADD BX, SIZE PROCESS
|
---|
697 | INC CL
|
---|
698 | CMP CL, MAX_PROCESSES + 1 ; Include PROC0
|
---|
699 | JB SHORT DH_LOOP_PROC
|
---|
700 | POPA
|
---|
701 | ASSUME BX:NOTHING
|
---|
702 | RET
|
---|
703 | DUMP_HANDLES ENDP
|
---|
704 |
|
---|
705 | ENDIF
|
---|
706 |
|
---|
707 | ;
|
---|
708 | ; Check reference counts
|
---|
709 | ;
|
---|
710 | ASSUME DS:SV_DATA
|
---|
711 | CHECK_HANDLES PROC NEAR
|
---|
712 | PUSHF
|
---|
713 | PUSHA
|
---|
714 | MOV AX, 0
|
---|
715 | CH_LOOP_REF: MOV DX, 0
|
---|
716 | MOV CX, MAX_PROCESSES + 1 ; Include PROC0
|
---|
717 | LEA BX, PROCESS_TABLE
|
---|
718 | ASSUME BX:PTR PROCESS
|
---|
719 | CH_LOOP_PROC: MOV SI, 0
|
---|
720 | CH_LOOP_HANDLE: CMP AX, [BX].P_HANDLES[SI]
|
---|
721 | JNE SHORT CH_NEXT_HANDLE
|
---|
722 | INC DX
|
---|
723 | CH_NEXT_HANDLE: ADD SI, 2
|
---|
724 | CMP SI, 2 * MAX_FILES
|
---|
725 | JB SHORT CH_LOOP_HANDLE
|
---|
726 | ADD BX, SIZE PROCESS
|
---|
727 | LOOP CH_LOOP_PROC
|
---|
728 | MOV DI, AX
|
---|
729 | SHL DI, 1
|
---|
730 | CMP DOS_REF_COUNT[DI], DX
|
---|
731 | JNE SHORT CH_FAILURE
|
---|
732 | INC AX
|
---|
733 | CMP AX, TOTAL_FILES
|
---|
734 | JB CH_LOOP_REF
|
---|
735 | ASSUME BX:NOTHING
|
---|
736 | CH_RET: POPA
|
---|
737 | POPF
|
---|
738 | RET
|
---|
739 | CH_FAILURE: LEA EDX, $CHECK_HANDLES
|
---|
740 | CALL OTEXT
|
---|
741 | CALL OCRLF
|
---|
742 | JMP SHORT CH_RET
|
---|
743 | CHECK_HANDLES ENDP
|
---|
744 |
|
---|
745 | ;
|
---|
746 | ; Call CHECK_HANDLES for -!1
|
---|
747 | ;
|
---|
748 | TALIGN 4
|
---|
749 | ASSUME DS:SV_DATA
|
---|
750 | MAYBE_CHECK_HANDLES PROC NEAR
|
---|
751 | TEST TEST_FLAGS, TEST_CHECK_HANDLES
|
---|
752 | JZ SHORT FIN
|
---|
753 | CALL CHECK_HANDLES
|
---|
754 | FIN: RET
|
---|
755 | MAYBE_CHECK_HANDLES ENDP
|
---|
756 |
|
---|
757 |
|
---|
758 | ;
|
---|
759 | ; Truncate a path name
|
---|
760 | ;
|
---|
761 | ; In: ES:EDI Pathname
|
---|
762 | ; PROCESS_PTR Pointer to process table entry
|
---|
763 | ;
|
---|
764 |
|
---|
765 | ASSUME DS:SV_DATA
|
---|
766 | TALIGN 4
|
---|
767 | TRUNCATE PROC NEAR
|
---|
768 | PUSHAD
|
---|
769 | PUSH FS
|
---|
770 | MOV BX, PROCESS_PTR ; Get PTE of current process
|
---|
771 | CMP BX, NO_PROCESS ; Is there a current process?
|
---|
772 | JE TRUNC_NO ; No -> do nothing
|
---|
773 | MOV ECX, -1 ; Drive letter unknown
|
---|
774 | MOV AL, ES:[EDI] ; Does the pathname start
|
---|
775 | CMP AL, "/" ; with / or \ ?
|
---|
776 | JE SHORT TRUNC_1 ; Yes -> look for special name
|
---|
777 | CMP AL, "\"
|
---|
778 | JNE SHORT TRUNC_CHECK ; No -> skip
|
---|
779 | TRUNC_1: MOV AL, ES:[EDI+1] ; Check for UNC pathname
|
---|
780 | CMP AL, "/"
|
---|
781 | JE SHORT TRUNC_UNC ; Yes -> UNC
|
---|
782 | CMP AL, "\"
|
---|
783 | JE SHORT TRUNC_UNC ; Yes -> UNC
|
---|
784 | LEA BX, $DIR_DEV
|
---|
785 | CALL DIR_CHECK ; \dev\ ?
|
---|
786 | JZ TRUNC_NO ; Yes -> do nothing
|
---|
787 | LEA BX, $DIR_PIPE ; (TODO: This is DOS, not OS/2)
|
---|
788 | CALL DIR_CHECK ; \pipe\ ?
|
---|
789 | JZ TRUNC_NO ; Yes -> do nothing
|
---|
790 | ;
|
---|
791 | ; We have a pathname that starts with / or \ and is not special. Prepend
|
---|
792 | ; the drive letter defined by the -r option, if -r is given.
|
---|
793 | ;
|
---|
794 | MOV BX, PROCESS_PTR ; Get PTE of current process
|
---|
795 | ASSUME BX:PTR PROCESS
|
---|
796 | CMP [BX].P_DRIVE, 0 ; Prepend drive?
|
---|
797 | JE SHORT TRUNC_CHECK ; No ->
|
---|
798 | ;
|
---|
799 | ; Prepend drive letter
|
---|
800 | ;
|
---|
801 | MOV DL, [BX].P_DRIVE ; Get drive letter (A-Z)
|
---|
802 | MOV CL, DL
|
---|
803 | AND ECX, 1FH ; Bit for -t option
|
---|
804 | ASSUME BX:NOTHING
|
---|
805 | MOV DH, ":" ; Insert drive and colon
|
---|
806 | PUSH EDI
|
---|
807 | DRIVE_MOVE: MOV AL, DL ; Insert two bytes
|
---|
808 | XCHG DL, ES:[EDI]
|
---|
809 | INC EDI
|
---|
810 | XCHG DL, DH
|
---|
811 | TEST AL, AL
|
---|
812 | JNZ SHORT DRIVE_MOVE
|
---|
813 | POP EDI
|
---|
814 | JMP SHORT TRUNC_CHECK
|
---|
815 |
|
---|
816 | ;
|
---|
817 | ; It's a UNC pathname
|
---|
818 | ;
|
---|
819 | TRUNC_UNC: MOV ECX, 0 ; Check bit 0
|
---|
820 | JMP SHORT TRUNC_CHECK
|
---|
821 |
|
---|
822 | ;
|
---|
823 | ; Check if we should truncate the pathname.
|
---|
824 | ;
|
---|
825 | TRUNC_CHECK: MOV BX, PROCESS_PTR ; Get PTE of current process
|
---|
826 | ASSUME BX:PTR PROCESS
|
---|
827 | CMP [BX].P_TRUNC, 0 ; Never truncate?
|
---|
828 | JE TRUNC_NO ; Yes -> do nothing
|
---|
829 | CMP [BX].P_TRUNC, -1 ; Always truncate?
|
---|
830 | JE SHORT TRUNC_YES ; Yes -> truncate
|
---|
831 | CMP ECX, -1 ; Drive known?
|
---|
832 | JNE SHORT TRUNC_CHECK_2 ; Yes -> skip
|
---|
833 | ;
|
---|
834 | ; Try to get the drive letter from the pathname
|
---|
835 | ;
|
---|
836 | MOV AL, ES:[EDI]
|
---|
837 | SUB AL, "A"
|
---|
838 | CMP AL, 26
|
---|
839 | JB SHORT TRUNC_CHECK_1
|
---|
840 | MOV AL, ES:[EDI]
|
---|
841 | SUB AL, "a"
|
---|
842 | CMP AL, 26
|
---|
843 | JAE SHORT TRUNC_CURDISK
|
---|
844 | TRUNC_CHECK_1: CMP BYTE PTR ES:[EDI+1], ":"
|
---|
845 | JE SHORT TRUNC_PLUS1
|
---|
846 | ;
|
---|
847 | ; We don't know the drive letter -- use the current disk
|
---|
848 | ;
|
---|
849 | TRUNC_CURDISK: MOV AH, 19H
|
---|
850 | INT 21H
|
---|
851 | TRUNC_PLUS1: MOV CL, AL
|
---|
852 | INC CL
|
---|
853 | AND ECX, 1FH
|
---|
854 | ;
|
---|
855 | ; Check the bit specified by ECX
|
---|
856 | ;
|
---|
857 | TRUNC_CHECK_2: BT [BX].P_TRUNC, ECX ; Truncate for this drive?
|
---|
858 | JNC SHORT TRUNC_NO ; No -> do nothing
|
---|
859 | ASSUME BX:NOTHING
|
---|
860 | TRUNC_YES: PUSH DS
|
---|
861 | MOV ESI, EDI ; Setup source pointer
|
---|
862 | MOV_FS_DS ; Access DBCS_LEAD_TAB with FS
|
---|
863 | ASSUME FS:SV_DATA
|
---|
864 | MOV_DS_ES
|
---|
865 | ASSUME DS:NOTHING
|
---|
866 | JMP SHORT TRUNC_NAME ; At start of name
|
---|
867 |
|
---|
868 | TALIGN 4
|
---|
869 | TRUNC_LOOP: LODS BYTE PTR DS:[ESI] ; Fetch character
|
---|
870 | TEST AL, AL ; End?
|
---|
871 | JE SHORT TRUNC_END ; Yes -> done
|
---|
872 | CMP AL, ":"
|
---|
873 | JE SHORT TRUNC_DIR
|
---|
874 | CMP AL, "\"
|
---|
875 | JE SHORT TRUNC_DIR
|
---|
876 | CMP AL, "/"
|
---|
877 | JE SHORT TRUNC_DIR
|
---|
878 | CMP AL, "."
|
---|
879 | JE SHORT TRUNC_EXT
|
---|
880 | MOV AH, 0
|
---|
881 | BT DBCS_LEAD_TAB, AX ; DBCS lead byte?
|
---|
882 | JC SHORT TRUNC_DBCS
|
---|
883 | TRUNC_STORE: TEST CL, CL ; Beyond maximum length?
|
---|
884 | JZ SHORT TRUNC_LOOP ; Yes -> don't store
|
---|
885 | STOS BYTE PTR ES:[EDI] ; Store character
|
---|
886 | DEC CL ; Adjust length counter
|
---|
887 | JMP SHORT TRUNC_LOOP ; Next character
|
---|
888 |
|
---|
889 | TRUNC_DBCS: CMP BYTE PTR DS:[ESI], 0 ; Invalid DBCS char?
|
---|
890 | JE SHORT TRUNC_STORE ; Yes -> store anyway
|
---|
891 | INC ESI ; Skip 2nd byte
|
---|
892 | CMP CL, 2 ; Can we store 2 bytes?
|
---|
893 | JB SHORT TRUNC_LOOP ; No -> drop both bytes
|
---|
894 | STOS BYTE PTR ES:[EDI] ; Store 1st byte
|
---|
895 | MOV AL, DS:[ESI-1]
|
---|
896 | STOS BYTE PTR ES:[EDI] ; Store 2nd byte
|
---|
897 | SUB CL, 2 ; Adjust length counter
|
---|
898 | JMP SHORT TRUNC_LOOP ; Next character
|
---|
899 |
|
---|
900 | TRUNC_DIR: STOS BYTE PTR ES:[EDI] ; Store character
|
---|
901 | TRUNC_NAME: MOV CX, 0008H ; Extension not seen, 8 chars
|
---|
902 | JMP SHORT TRUNC_LOOP ; Next character
|
---|
903 |
|
---|
904 | TRUNC_EXT: CMP CX, 0103H ; Previous character a dot?
|
---|
905 | JE SHORT TRUNC_DOTS ; Yes -> keep ".."
|
---|
906 | TEST CH, CH ; Extension seen?
|
---|
907 | JNZ SHORT TRUNC_STOP ; Yes -> stop storing
|
---|
908 | TRUNC_DOTS: STOS BYTE PTR ES:[EDI] ; Store dot character
|
---|
909 | MOV CX, 0103H ; Extension seen, 3 characters
|
---|
910 | JMP SHORT TRUNC_LOOP ; Next character
|
---|
911 |
|
---|
912 | TRUNC_STOP: MOV CL, 0 ; Don't store characters
|
---|
913 | JMP SHORT TRUNC_LOOP ; Next character
|
---|
914 |
|
---|
915 | TRUNC_END: STOS BYTE PTR ES:[EDI]
|
---|
916 | POP DS
|
---|
917 | TRUNC_NO: POP FS
|
---|
918 | POPAD
|
---|
919 | RET
|
---|
920 | TRUNCATE ENDP
|
---|
921 |
|
---|
922 | ASSUME FS:NOTHING
|
---|
923 |
|
---|
924 | TALIGN 4
|
---|
925 | DIR_CHECK PROC NEAR
|
---|
926 | PUSH EDI
|
---|
927 | DIR_CHECK_1: INC EDI
|
---|
928 | MOV AL, ES:[EDI]
|
---|
929 | CMP BYTE PTR [BX], 0
|
---|
930 | JE SHORT DIR_CHECK_2
|
---|
931 | CALL UPPER
|
---|
932 | CMP AL, [BX]
|
---|
933 | JNE SHORT DIR_CHECK_8
|
---|
934 | INC BX
|
---|
935 | JMP SHORT DIR_CHECK_1
|
---|
936 |
|
---|
937 | DIR_CHECK_2: CMP AL, "/"
|
---|
938 | JE SHORT DIR_CHECK_8
|
---|
939 | CMP AL, "\"
|
---|
940 | DIR_CHECK_8: POP EDI
|
---|
941 | RET
|
---|
942 | DIR_CHECK ENDP
|
---|
943 |
|
---|
944 | SV_CODE ENDS
|
---|
945 |
|
---|
946 |
|
---|
947 | INIT_CODE SEGMENT
|
---|
948 |
|
---|
949 | ASSUME CS:INIT_CODE, DS:NOTHING
|
---|
950 |
|
---|
951 | ;
|
---|
952 | ; Initialize the DOS_REF_COUNT table and the file handles of PROC0.
|
---|
953 | ;
|
---|
954 | ; To speed things up, assume that at most handles 0, 1, and 2 are
|
---|
955 | ; inherited.
|
---|
956 | ;
|
---|
957 | ASSUME DS:SV_DATA
|
---|
958 | INIT_FILEIO PROC NEAR
|
---|
959 | ;
|
---|
960 | ; Initially, no file is referenced.
|
---|
961 | ;
|
---|
962 | MOV BX, 0
|
---|
963 | IF_ZERO_REF: MOV DOS_REF_COUNT[BX], 0
|
---|
964 | ADD BX, 2
|
---|
965 | CMP BX, 2 * TOTAL_FILES
|
---|
966 | JB IF_ZERO_REF
|
---|
967 | ;
|
---|
968 | ; Initialize the P_HANDLES array of PROC0, setting reference counts
|
---|
969 | ; as required.
|
---|
970 | ;
|
---|
971 | MOV BX, 0 ; File handle
|
---|
972 | MOV DI, 0 ; Index
|
---|
973 | IF_LOOP: MOV PROC0.P_HFLAGS[DI], 0 ; Clear handle flags
|
---|
974 | MOV AX, 4400H ; Get device data
|
---|
975 | INT 21H
|
---|
976 | JC SHORT IF_NOT_OPEN
|
---|
977 | MOV PROC0.P_HANDLES[DI], BX
|
---|
978 | INC DOS_REF_COUNT[DI]
|
---|
979 | JMP SHORT IF_NEXT
|
---|
980 |
|
---|
981 | IF_NOT_OPEN: MOV PROC0.P_HANDLES[DI], NO_FILE_HANDLE
|
---|
982 | IF_NEXT: ADD DI, 2
|
---|
983 | INC BX
|
---|
984 | CMP BX, MAX_FILES ; File handles per process!
|
---|
985 | JB SHORT IF_LOOP
|
---|
986 | RET
|
---|
987 | INIT_FILEIO ENDP
|
---|
988 |
|
---|
989 | INIT_CODE ENDS
|
---|
990 |
|
---|
991 | END
|
---|