| 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
|
|---|