home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l350 / 3.ddi / EXAMPLES / MSC / CRITERR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-11  |  4.6 KB  |  194 lines

  1. // CRITERR.C -- Use _seterrormode() to control critical error
  2. //        (INT 24h) processing.
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <signal.h>
  8. #include <conio.h>
  9. #include <ctype.h>
  10. #include <dos.h>
  11. #include <fcntl.h>
  12. #include <errno.h>
  13. #include <pldos32.h>
  14. #include <pharlap.h>
  15.  
  16. //
  17. // Prot mode segment regs, needed by critical error handler in CRITHAND.ASM
  18. //
  19. USHORT CSReg;
  20. USHORT DSReg;
  21. USHORT ESReg;
  22. USHORT FSReg;
  23. USHORT GSReg;
  24.  
  25. void CauseCritErr(void);
  26. int __cdecl ProcessCritErr(FARPTR pIntStackFrame);
  27. void CritErrHand();    // in CRITHAND.ASM
  28.  
  29. int main()
  30. {
  31.     REALPTR    RealCritErrVec;
  32.     FARPTR ProtCritErrVec;
  33.     FARPTR OurCritErrHand;
  34.  
  35. //
  36. // Get our segment registers, for use by critical error handler
  37. //
  38.     _asm {
  39.         mov CSReg,cs
  40.         mov DSReg,ds
  41.         mov ESReg,es
  42.         mov ax,fs
  43.         mov FSReg,ax
  44.         mov ax,gs
  45.         mov GSReg,ax
  46.     }
  47.  
  48. //
  49. // Tell the user to open the A: floppy door, so this program will be
  50. // able to cause critical errors.
  51. //
  52.     printf("Please open the A: floppy disk door, press any key to \
  53. continue\n");
  54.     _getch();
  55.  
  56. //
  57. // Cause a critical error by attempting to read from the open A: floppy
  58. // disk drive.  The DOS Abort/Retry/Fail query should appear.
  59. //
  60.     printf("\n** DOS should receive this critical error **\n");
  61.     CauseCritErr();
  62.  
  63. //
  64. // Save previous critical error (INT 24h) handler, and install our
  65. // handler to always get control in protected mode.
  66. //
  67.     _dx_rmiv_get(0x24, &RealCritErrVec);
  68.     _dx_pmiv_get(0x24, &ProtCritErrVec);
  69.     FP_SET(OurCritErrHand, CritErrHand, CSReg);
  70.     _dx_apmiv_set(0x24, OurCritErrHand);
  71.  
  72. //
  73. // Cause a critical error again.  Our handler should get control.
  74. //
  75.     printf("\n** Our critical error handler should get this one **\n");
  76.     CauseCritErr();
  77.  
  78. //
  79. // Set critical error to always fail, and cause a critical error
  80. //
  81.     _seterrormode(_CRIT_ERROR_FAIL);
  82.     printf("\n** This call should just be failed immediately **\n");
  83.     CauseCritErr();
  84.  
  85. //
  86. // Set critical error to be handled, and cause a critical error
  87. //
  88.     _seterrormode(_CRIT_ERROR_PROMPT);
  89.     printf("\n** Our handler should get get control again **\n");
  90.     CauseCritErr();
  91.  
  92. //
  93. // Restore original critical error vectors
  94. //
  95.     _dx_rpmiv_set(0x24, ProtCritErrVec, RealCritErrVec);
  96.  
  97.     return 0;
  98. }
  99.  
  100. void CauseCritErr(void)
  101. {
  102.     int    handle;
  103.     UINT    errv;
  104.  
  105.     printf("Causing critical error by opening file on A: drive\n");
  106.     errv = _dos_open("A:\foo", _O_RDONLY, &handle);
  107.     if (errv == 0)
  108.         printf("Open succeeded!!!\n");
  109.     else
  110.     {
  111.         printf("Open failed, DOS error code = %d\n", errv);
  112.         switch (errno)
  113.         {
  114.         case EACCES:
  115.             printf("Access denied\n");
  116.             break;
  117.         case EINVAL:
  118.             printf("Invalid access mode\n");
  119.             break;
  120.         case EMFILE:
  121.             printf("Too many open file handles\n");
  122.             break;
  123.         case ENOENT:
  124.             printf("Path or file not found\n");
  125.             break;
  126.         default:
  127.             printf("Unknown errno: %d\n", errno);
  128.             break;
  129.         }
  130.     }
  131.     return;
  132. }
  133.  
  134. //
  135. // ProcessCritErr - This routine is called by the assembly language
  136. //        critical error handler routine in CRITHAND.ASM
  137. //
  138. // At critical error time, you can only make DOS calls 01h through 0Ch,
  139. // so we can't use any C library calls that would use any other DOS calls
  140. // (such as printf(), which uses Write File to write to standard output).
  141. //
  142. // Returns action code (0-3) to return to DOS in AL.
  143. //
  144. int __cdecl ProcessCritErr(FARPTR pIntStackFrame)
  145. {
  146.     INT_STACK_FRAME IntFrame;    // protected mode interrupt stack frame
  147.     struct {
  148.         USHORT dos_ax;
  149.         USHORT dos_bx;
  150.         USHORT dos_cx;
  151.         USHORT dos_dx;
  152.         USHORT dos_si;
  153.         USHORT dos_di;
  154.         USHORT dos_bp;
  155.         USHORT dos_ds;
  156.         USHORT dos_es;
  157.         USHORT dos_ip;
  158.         USHORT dos_cs;
  159.         USHORT dos_flags;
  160.     } DosCEFrame;            // real mode DOS INT 24h stack frame
  161.     REALPTR    pRealCEFrame;        // Real mode ptr to critical err frame
  162.     UCHAR    ch;
  163.     UCHAR    buf[25];
  164.  
  165. //
  166. // Get the interrupt stack frame, and use that to get the address of the
  167. // real mode stack frame when DOS issued the INT 24h
  168. //
  169.     ReadFarMem(&IntFrame, pIntStackFrame, sizeof(IntFrame));
  170.     if (IntFrame.int_inum != 0x24 || !(IntFrame.int_dxfl & IFL_RMODE))
  171.     {
  172.         printf("Not INT 24h, or didn't originate in real mode!!\n");
  173.         return 3;
  174.     }
  175.     RP_SET(pRealCEFrame, IntFrame.int_esp, IntFrame.int_ss);
  176.     ReadRealMem(&DosCEFrame, pRealCEFrame, sizeof(DosCEFrame));
  177.     _dos_str_out("Critical error occurred on INT 21h function $");
  178.     _itoa((int) (DosCEFrame.dos_ax >> 8), buf, 16);
  179.     strcat(buf, "h\r\n$");
  180.     _dos_str_out(buf);
  181.  
  182. //
  183. // Ask the user what action to take
  184. //
  185.     do {
  186.         _dos_str_out("Enter action code (0=ignore, 1=retry, \
  187. 2=terminate, 3=fail): $");
  188.         _dos_char_ine(&ch);
  189.         _dos_str_out("\r\n$");
  190.     } while (ch < '0' || ch > '3');
  191.  
  192.     return (int) (ch - '0');
  193. }
  194.