Interrupt 24h Critical Error Handler (0:0090h) When a critical error occurs within DOS, control is transferred to an error handler with an int 24h. This may be the standard DOS error handler (ABORT, RETRY, IGNORE) or a user-written routine. cri\tter.asm On entry to the error handler, AH will have its bit 7=0 (high order bit) if the error was a disk error (probably the most common error), bit 7=1 if not. BP:SI contains the address of a Device Header Control Block from which additional information can be retrieved (see below). The register is set up for a retry operation and an error code is in the lower half of the DI register with the upper half undefined. These are the error codes: The user stack is in effect and contains the following from top to bottom: IP DOS registers from issuing int 24h CS int 24h flags AX user registers at time of signal BX Int\21 request CX DX SI DI BP DS ES IP from original Int\21 CS flags To reroute the critical error handler to a user-writen critical error handler, the following should be done: Before an int 24h occurs: 1) The user application initialization code should save the int 24h vector and replace the vector with one pointing to the user error routine. When the int 24h occurs: 2) When the user error routine received control it should push the flag registers onto the stack and execute a far call to the original int 24h vector saved in step 1. 3) DOS gives the appropriate prompt, and waits for user input (Abort, Retry, Ignore, Fail). After the user input, DOS returns control to the user error routine instruction following the far call. 4) The user error routine can now do any tasks nescessary. To return to the original application at the point the error occurred, the error routine needs to execute an IRET instruction. Otherwise, the user error routine should remove the IP, CS, and flag registers from the stack. Control can then be passed to the desired point. Provides the following values in registers on entry to the interrupt handler: entry AH status byte (bits) 7 0 disk I/O hard error 1 other error - if block device, bad FAT - if char device, code in DI 6 unused 5 0 if IGNORE is not allowed 1 if IGNORE is allowed 4 0 if RETRY is not allowed 1 if RETRY is allowed 3 0 if FAIL is not allowed 1 if FAIL is allowed 2 \\ disk area of error 00 = DOS area 01 = FAT 1 / 10 = root dir 11 = data area 0 0 if read operation 1 if write operation AL drive number if AH bit 7 = 1, otherwise undefined If it is as hard error on disk (AH bit 7=0), register AL contains the failing drive number (0=A:, 1=B:, etc.). BP:SI address of a Device Header Control Block for which error occurred block device if high bit of BP:SI+4 = 1 Provides the following values in registers on entry to the interrupt handler: low byte of DI: error code (note: high byte is undefined) error code description 00h attempt to write on write-protected diskette 01h unknown unit 02h drive not ready 03h unknown command 04h data error (bad CRC) 05h bad request structure length 06h seek error 07h unknown media type 08h sector not found 09h printer out of paper 0Ah write fault 0Bh read fault 0Ch general failure 0Fh invalid disk change (DOS 3.x+) 10h (DOS 3.x) FCB unavailable 11h (DOS 3.x) sharing buffer overflow The handler must return this information: The registers are set such that if an IRET is executed, DOS responds according to (AL) as follows: AL 00h ignore the error 01h retry the operation 02h terminate via Int\22 03h fail the system call that is in progress (DOS 3.x+) note 1) Be careful when choosing to ignore a response because this causes DOS to beleive that an operation has completed successfully when it may not have. 2) If the error was a character device, the contents of AL are invalid. Interrupt 24h Critical Error Handler Other errors If AH bit 7=1, the error occurred on a character device, or was the result of a bad memory image of the Struct -FAT. The device header passed in BP:SI can be examined to determine which case exists. If the attribute byte high-order bit indicates a block device, then the error was a bad FAT. Otherwise, the error is on a character device. If a character device is involved, the contents of AL are unpredictable, the error code is in DI as above. Notes: 1. Before giving this routine control for disk errors, DOS performs several retries. The number of retries varies according to the DOS version. 2. For disk errors, this exit is taken only for errors occurring during an Int\21 function call. Is not used for errors during Int\25 or Int\26. 3. This routine is entered in a disabled state. 4. All registers must be preserved. 5. This interrupt handler should refrain from using DOS function calls. If necessary, it may use calls 01h through 12h. Use of any other call destroys the DOS stack and leaves DOS in an unpredictable state. 6. The interrupt handler must not change the contents of the device header. Interrupt 24h Critical Error Handler Other errors 7. If the interrupt handler handles errors itself rather than returning to DOS, it should restore the application program's registers from the stack, remove all but the last three words on the stack, then issue an IRET. This will return to the program immediately after the Int\21 that experienced the error. Note that if this is done DOS will be in an unstable state until a function call higher than 12h is issued, therefore not recommended. 8. For DOS 3.x, IGNORE requests (AL=0) are converted to FAIL for critical errors that occur on FAT or DIR sectors. 9. For DOS 3.10 up, IGNORE requests (AL=0) are converted to FAIL requests for network critical errors (50-79). Interrupt 24h Critical Error Handler The device header pointed to by BP:SI is as follows: DWORD Pointer to next device (0FFFFh if last device) WORD Attributes: Bit 15 1 if character device. If bit 15 is 1: Bit 0 = 1 if current standard input Bit 1 = 1 if current standard output Bit 2 = 1 if current NULL device Bit 3 = 1 if current CLOCK device 0 if block device Bit 14 is the Device\IOCTLs bit WORD pointer to Device\drivers -strategy entry point WORD pointer to Device\drivers -interrupt entry point 8-BYTE character device named field for block devices. The first byte is the number of units. To tell if the error occurred on a block or character device, look at bit 15 in the attribute field (WORD at BP:SI+4). If the name of the character device is desired, look at the eight bytes starting at BP:SI+10. Interrupt 24h Critical Error Handler HANDLING OF INVALID RESPONSES (DOS 3.x) A) If IGNORE (AL=0) is specified by the user and IGNORE is not allowed (bit 5=0), make the response FAIL (AL=3). B) If RETRY (AL=1) is specified by the user and RETRY is not allowed (bit 4=0), make the response FAIL (AL=3). C) If FAIL (AL=3) is specified by the user and FAIL is not allowed (bit 3=0), make the response ABORT. (AL=2)