home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / CRITERCL.ZIP / CRITERR.ASM
Encoding:
Assembly Source File  |  1987-07-02  |  6.4 KB  |  178 lines

  1. ;------------------------------------------------------------------------------
  2. ;
  3. ;  So I have to have this clipper-compiled application ready to
  4. ;  distribute in a week.  It's bad enough that all these new reports
  5. ;  have to be written and a bunch of other things changed, but there is
  6. ;  still the problem of the critical error handler to be resolved.
  7. ;
  8. ;  Clipper programs that manipulate devices end up using the dos
  9. ;  critical error handler -- the one that asks "abort, retry or ignore?"
  10. ;  The worst thing about this for the clipper user is that if their user
  11. ;  takes the printer offline for just a second, the dos function that
  12. ;  clipper uses to print freaks and passes control to the critical error
  13. ;  handler, which at best annoys the user and at worst ends up aborting
  14. ;  the application.  Same goes for accessing floppies that have no disk
  15. ;  in them or an unformatted disk.
  16. ;
  17. ;  Well, it's actually fairly easy to replace the address of the default
  18. ;  critical error handler with the address of one of your own (dos
  19. ;  cleans up after you when your program terminates, so that's no
  20. ;  problem)  but, what should it do?
  21. ;
  22. ;  Well, all I wanted was two things:  ignore printer errors, and report
  23. ;  disk errors as failed.
  24. ;
  25. ;  this routine does that. it doesn't do much else, and doesn't do it
  26. ;  too well, but it works and it's better than nothing.
  27. ;
  28. ;  if you're printing, and the user turns off the printer or takes it
  29. ;  offline, the program just keeps on trying to print (forever!)
  30. ;
  31. ;  if you use the file() function, it will fail if done against a floppy
  32. ;  drive that has no disk or an unformatted disk.
  33. ;
  34. ;  the dbase/clipper dir command seems to pass control to another copy
  35. ;  of dos to do its work, and so it picks up on another copy of the
  36. ;  default critical error handler.  However, with this routine in place,
  37. ;  if the user responds to the a/r/e message with A for abort, the
  38. ;  application program will not be aborted (it would otherwise..)
  39. ;
  40. ;  how to use: link  CRITINST.OBJ in with your clipper application, and
  41. ;  somewhere, preferably at the start of everything, install it with a
  42. ;  line like    CRITINST()
  43. ;  that's it.
  44. ;
  45. ;  if you don't have the obj, just compile this with:   MASM CRITINST;
  46. ;
  47. ;  if you want to expand upon it to do other wonderful things, go right ahead.
  48. ;
  49. ;  Unreservedly fosted off into the public domain by David Michmerhuizen,
  50. ;                                                    Fremont  CA  1987.
  51. ;
  52. ;------------------------------------------------------------------------------
  53.  
  54. EXTRN   _PARNI:FAR      ; use to get int arguments.
  55. EXTRN   _RET:FAR        ; how clipper wants us to return
  56.  
  57. _PROG SEGMENT           ; Clippers segment name
  58. ASSUME CS:_PROG
  59.  
  60. PUBLIC CRITINST         ; Make our name available
  61.  
  62. CRITINST PROC   FAR
  63.  
  64.          PUSH     AX
  65.          PUSH     BX
  66.          PUSH     CX
  67.          PUSH     DX
  68.          mov      ah,25h
  69.          mov      al,23h
  70.          push     ds
  71.          mov      dx,seg    BRKHAND
  72.          mov      ds,dx
  73.          mov      dx,offset BRKHAND
  74.          int     21H            ;local error handler is in place
  75.          POP     ds
  76.          mov     ah,25H         ;function to replace an int vector
  77.          mov     al,24H         ;DOS critical error interrupt number
  78.          push    ds
  79.          mov     dx,seg CRITHAND
  80.          mov     ds,dx
  81.          mov     dx,offset CRITHAND
  82.          int     21H            ;local error handler is in place
  83.          POP     ds
  84.          POP      DX
  85.          POP      CX
  86.          POP      BX
  87.          POP      AX
  88.  
  89.          CALL     _RET                ;Clipper housekeeping
  90.          RET                          ;'real' return
  91.  
  92. CRITINST ENDP
  93.  
  94.  
  95. devhdr_addr label dword        ;these values are saved upon entry
  96. devhdr_off       dw ?          ;its stuff dos makes available so we
  97. devhdr_seg       dw ?          ;can figure out what's goin' on.
  98. save_ax          dw ?          ;
  99. save_di          dw ?          ;
  100.  
  101. save_sp          dw ?          ;these are used in a CANCEL request
  102. app_err          dw ?
  103.  
  104.  
  105. CRITHAND PROC    FAR
  106.          mov     cs:save_sp,sp   ;save the stack position at start
  107.          push    ax              ;save DOS's registers
  108.          push    bx
  109.          push    cx
  110.          push    dx
  111.          push    si
  112.          push    di
  113.          push    bp
  114.          push    es
  115.          push    ds
  116.          push    cs
  117.          pop     ds
  118.          mov     devhdr_off,si   ;save address of the device header
  119.          mov     devhdr_seg,bp
  120.          mov     save_ax,ax      ;save err type & read/write bit flags
  121.          mov     save_di,di      ;save error code
  122.          and     di,00ffH        ;get critical error code
  123.          add     di,19           ;convert to DOS error code
  124.          mov     app_err,di      ;save in case we return directly to
  125.                                  ; the interrupted application
  126.          mov     ax,save_ax
  127.          test    ah,80H          ;disk error ?
  128.          jnz     ce_40           ; no, process character device error
  129.          jmp     ce_50           ; yes, process disk error
  130.  
  131.  
  132. ce_40:   ;-------------------- action taken on RETRY request
  133.  
  134.          pop     ds            ;restore DOS registers
  135.          pop     es
  136.          pop     bp
  137.          pop     si
  138.          pop     di
  139.          pop     dx
  140.          pop     cx
  141.          pop     bx
  142.          pop     ax
  143.          mov     al,1          ;set "Retry" return code
  144.          iret                  ;and exit to DOS
  145.  
  146. ce_50:   ;--------------------- action taken on CANCEL request
  147.          mov     sp,cs:save_sp ;locally-saved regs are irrelevant
  148.          pop     ax            ;and discard DOS IP
  149.          pop     ax            ;            DOS CS
  150.          pop     ax            ;            DOS flags
  151.  
  152.          pop     ax            ;restore application's registers
  153.          pop     bx
  154.          pop     cx
  155.          pop     dx
  156.          pop     si
  157.          pop     di
  158.          pop     bp
  159.          pop     ds
  160.          pop     es
  161.  
  162.          push    bp                 ;set the carry flag (on the stack)
  163.          mov     bp,sp              ; so the application will
  164.          or      word ptr [bp+6],1  ; notice that an error occurred
  165.          pop     bp
  166. ;        mov     ax,cs:app_err      ;and pass back a DOS error code
  167.          mov     al,2               ;cancel thru the ^c handler we installed
  168.          iret
  169.  
  170. CRITHAND ENDP
  171.  
  172. BRKHAND  PROC  FAR
  173.          IRET
  174. BRKHAND  ENDP
  175.  
  176. _PROG ENDS
  177.       END
  178.