============================================================================== BBS: -=- Edge of the Century -=- To: DANIEL KEMPTON Date: 01-20-93 (05:13) From: GREG VIGNEAULT Number: 3196 [140] Pascal Subj: CRITICAL ERROR HANDLER Status: Public ------------------------------------------------------------------------------ DK> Can anyone PLEASE give me information on how to write a critical > error handler. Below is a quick'n-dirty critical error handler, written without any Asm (so is usable from TP v4.0+). To test it, put a write- protected diskette in drive A:, then run the program. It should report error #19 (13 hex, disk write-protected). It'll need to be modified & trimmed to your purpose. You might code your handler to simply ignore errors, then let your main program take appropriate action, depending on the error, etc. DOS functions $00..$0C, $30, and $59 should be safe calls from the handler. Function $59 will return the extended error information code that you'll need to check (eg. #32 = share violation), as well as other data - which you can read up on, in a Dos reference text. I've used one byte of the DOS intra-process communication area (at $40:$F0) to return the value needed to tell Dos what to do about the error, rather than juggle registers. This should be okay. This code is cramped, to fit into a single message ... {*******************************************************************} PROGRAM Example; { Critical Error Handler } USES Dos, { import MsDos, GetIntVec, SetIntVec, Registers } Crt; { import CheckBreak } VAR OldISR : POINTER; { to save original ISR ptr } Reg : Registers; { to access CPU registers } errNumber : WORD; { extended error code } errClass, { error class } errAction, { recommended action } errLocus : BYTE; { error locus } FileName : String[13]; { for ASCIIZ file name } {-------------------------------------------------------------------} PROCEDURE cErrorISR( AX,BX,CX,DX,SI,DI,DS,ES,BP : WORD); Interrupt; BEGIN { This is it! ... } InLine($FB); { STI (allow interrupts) } Reg.AX := $3000; MsDos(Reg); { fn: get Dos version } IF (Reg.AH < 3) THEN Reg.AL := 3 { if less than Dos 3+ :FAIL } ELSE BEGIN { else take a closer look.. } Reg.AH := $59; Reg.BX := 0; { fn: get extended info } MsDos( Reg ); { call Dos } errNumber := Reg.AX; { set|clear error number } errClass := Reg.BH; errAction := Reg.BL; errLocus := Reg.CH; WriteLn; Write( 'Critical error (#', errNumber, ') ' ); REPEAT WriteLn; { loop for user response } Write( 'Abort, Retry, Ignore, Fail (A|R|I|F) ? ',#7); Reg.AH := 1; MsDos(Reg); { get user input, via Dos } UNTIL UpCase(CHR(Reg.AL)) IN ['A','R','I','F']; CASE CHR(Reg.AL) OF { ... depending on input } 'i','I' : Reg.AL := 0; { = ignore error } 'r','R' : Reg.AL := 1; { = retry the action } 'a','A' : Reg.AL := 2; { = abort } 'f','F' : Reg.AL := 3; { = fail } END; {case} END; {if Reg.AH} Mem[$40:$F0] := Reg.AL; { to tell Dos what to think } InLine( $8B/$E5/ { mov sp,bp } $5D/$07/$1F/$5F/$5E/ { pop bp,es,ds,di,si } $5A/$59/$5B/$58/ { pop dx,cx,bx,ax } $06/ { push es } $2B/$C0/ { sub ax,ax } $8E/$C0/ { mov es,ax } $26/$A0/$F0/$04/ { mov al,es:[4F0h] } $07/ { pop es } $CF); { iret } END {cErrorISR}; {-------------------------------------------------------------------} BEGIN { the main program... } CheckBreak := FALSE; { don't allow Ctrl-Break! } errNumber := 0; { clear the error code } GetIntVec( $24, OldISR ); { save current ISR vector } SetIntVec( $24, @cErrorISR ); { set our ISR } {===========================================================} { insert your test code here ... } FileName := 'A:TEST.TXT' + CHR(0); { ASCIIZ file name } Reg.DS := SEG( FileName ); { file name segment } Reg.DX := OFS( FileName[1] ); { file name offset } Reg.CX := 0; { normal attribute } Reg.AH := $3C; { fn: create file } MsDos( Reg ); { via Dos } {===========================================================} IF (errNumber <> 0) THEN BEGIN Write(#13#10#10,'For error #',errNumber,', user requested '); CASE Mem[$40:$F0] OF 0 : WriteLn('IGNORE'); { just your imagination } 1 : WriteLn('RETRY'); { ... endless futility ? } 2 : WriteLn('ABORT'); { DOS won't come back here! } 3 : WriteLn('FAIL'); { call technical support } END; {case} END; {if errNumber<>0} SetIntVec( $24, OldISR ); { must restore original ISR } END. {*******************************************************************} Greg_ Jan.20.1993.Toronto.Canada. greg.vigneault@bville.gts.org --- * Baudeville BBS Toronto CANADA 416-283-0114 2200+ confs * PostLink(tm) v1.04 BAUDEVILLE (#1412) : RelayNet(tm)