home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / KBTRAP.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  6KB  |  216 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. **  KBTRAP.C - Traps Ctrl-Alt-Del, Ctrl-C, Ctrl-Break, SysRq, PrintScreen,
  5. **             and Pause keys.
  6. **
  7. **  Derived from public domain sources, uses SNIPPETS header files
  8. */
  9.  
  10. #include <stdlib.h>
  11. #include <dos.h>
  12. #include "pchwio.h"
  13. #include "sniptype.h"
  14. #include "sniprint.h"
  15.  
  16. #define CTRLALT         (0x08|0x04) /* bit flags set in kbstat()        */
  17. #define CTRL            (0x04)      /* bit flags set in kbstat()        */
  18. #define ALT             (0x08)      /* bit flags set in kbstat()        */
  19. #define DELSCAN         0x53        /* keyboard scan code for <Del>     */
  20. #define CSCAN           0x2E        /* keyboard scan code for <C>       */
  21. #define BREAKSCAN       0x46        /* keyboard scan code for <Break>   */
  22. #define PRTSCRNSCAN     0x37        /* keyboard scan code for <PrtScrn> */
  23. #define SYSREQSCAN      0x54        /* keyboard scan code for <SysReq>  */
  24. #define MULTI2SCAN      0xE0        /* 1st byte of 2 byte scan code     */
  25. #define MULTI3SCAN      0xE1        /* 1st byte of 3 byte scan code     */
  26. #define KEYPORT         0x60        /* keyboard scan code port          */
  27. #define CONTROLLERPORT  0x20        /* interrupt controller port        */
  28. #define kbstat()        Peekw(0,0x417) /* BIOS data area - kb flags     */
  29.  
  30. #define keyport()      inp(KEYPORT)
  31.             /* macro that returns the scancode of the key that caused   */
  32.             /* the interrupt                                            */
  33.  
  34. #define install()      (oldkbisr=getvect(0x09),setvect(0x09,newkbisr))
  35.             /* installation macro, installs newkbisr() in the keyboard  */
  36.             /* interrupt chain                                          */
  37.  
  38. #define uninstall()       setvect(0x09,oldkbisr)
  39.             /* removal macro, call to remove newkbisr() from interrupt  */
  40.             /* chain.  oldkbisr()  must be removed before program ends  */
  41.  
  42. static void (INTERRUPT FAR * oldkbisr)(void);
  43.             /* address of old keyboard ISR                              */
  44.  
  45. static Boolean_T PrtScrnPending = False_;
  46.             /* semaphore to flag pending print screen operations        */
  47.  
  48. static void cleanup(void);
  49.             /* atexit()-registered version of uninstall() macro         */
  50.  
  51. static Boolean_T KBtrap_active;
  52. static Boolean_T KBtrap_installed = False_;
  53.  
  54. static void KBtrap(void);
  55. static void cleanup(void);
  56. static void INTERRUPT FAR newkbisr(void);
  57.  
  58.  
  59. /*
  60. **  Called to activate trapping the system keys. When called the first time,
  61. **  it calls KBtrap() to install the ISR. Registers the ISR removal function
  62. **  using atexit() so the ISR will always be uninstalled upon program
  63. **  termination.
  64. */
  65.  
  66. void activate_KBtrap(void)
  67. {
  68.       if (!KBtrap_installed)
  69.             KBtrap();
  70.       KBtrap_active = True_;
  71. #ifdef TEST
  72.       puts("Keyboard trap activated");
  73. #endif
  74. }
  75.  
  76. /*
  77. **  Called to deactivate trapping the system keys, but leave ISR installed.
  78. **  If the user had attempted a PrintScreen operation while the trap was
  79. **  active, it is now called.
  80. */
  81.  
  82. void deactivate_KBtrap(void)
  83. {
  84.       KBtrap_active = False_;
  85. #ifdef TEST
  86.       puts("Keyboard trap deactivated");
  87. #endif
  88.       if (PrtScrnPending)
  89.       {
  90.             if (Success_ == PrtScrn())
  91.                   PrtScrnPending = False_;
  92.       }
  93. }
  94.  
  95. /*
  96. **  Traps system keys - Ignores Ctrl-Alt-Del, Ctrl-C, Ctrl-Break, SysRq,
  97. **                      and Pause.
  98. **
  99. **                      Defers execution of PrintScreen
  100. */
  101.  
  102. static void INTERRUPT FAR newkbisr(void)
  103. {
  104.       static int count = 0;
  105.       int key = keyport();
  106.  
  107.       if (KBtrap_active)
  108.       {
  109.             if (count)
  110.             {
  111.                   unsigned char kbin;
  112.  
  113.                   --count;
  114.  
  115.                   if (PRTSCRNSCAN == key)
  116.                         PrtScrnPending = True_;
  117. IGNORE:
  118.                   kbin = (unsigned char)inp(KEYPORT+1); /* reset keyboard  */
  119.                   outp(KEYPORT+1, kbin|0x80);
  120.                   outp(KEYPORT+1, kbin);
  121.                   disable();
  122.                   outp(CONTROLLERPORT,0x20); /* tell controller to shut up */
  123.                   enable();
  124.                   return;
  125.             }
  126.             else switch (key)
  127.             {
  128.             case MULTI2SCAN:
  129.                   count = 1;
  130.                   goto IGNORE;
  131.  
  132.             case MULTI3SCAN:
  133.                   count = 2;
  134.                   goto IGNORE;
  135.  
  136.             case DELSCAN:
  137.                   if (CTRLALT == (kbstat() & CTRLALT))
  138.                         goto IGNORE;
  139.                   break;
  140.                   
  141.             case PRTSCRNSCAN:
  142.                   PrtScrnPending = True_;
  143.                   goto IGNORE;
  144.                   
  145.             case CSCAN:
  146.             case BREAKSCAN:
  147.                   if (CTRL == (kbstat() & CTRL))
  148.                         goto IGNORE;
  149.                   break;
  150.                   
  151.             case SYSREQSCAN:
  152.                   goto IGNORE;
  153.             }
  154.       }
  155.       else
  156.       {
  157.             if (count)
  158.             {
  159.                   --count;
  160.                   return;
  161.             }
  162.       }
  163.       oldkbisr();                         /* chain to old keyboard isr */
  164. }
  165.  
  166. static void KBtrap(void)
  167. {
  168.       install();
  169.       atexit(cleanup);
  170.       KBtrap_installed = True_;
  171. #ifdef TEST
  172.       puts("Keyboard trap installed");
  173. #endif
  174. }
  175.  
  176. static void cleanup(void)
  177. {
  178.       uninstall();
  179. #ifdef TEST
  180.       puts("Keyboard trap uninstalled");
  181. #endif
  182. }
  183.  
  184. #ifdef TEST
  185.  
  186. #include <stdio.h>
  187. #include <conio.h>
  188. #include <signal.h>
  189. #include <errno.h>
  190.  
  191. main()
  192. {
  193.       int ch = 0;
  194.  
  195.       puts("This is a test of Ctrl-Alt-Del disabling.");
  196.       puts("Press any key, but only Esc should stop this program.");
  197.       
  198.       activate_KBtrap();
  199.  
  200.       while (0x1b != ch)
  201.       {
  202.             if (kbhit())
  203.             {
  204.                   ch = getch();
  205.                   printf("key value = %02Xh, PrtScrnPending = %d\n",
  206.                          ch, PrtScrnPending);
  207.             }
  208.       }
  209.       
  210.       deactivate_KBtrap();
  211.  
  212.       return EXIT_SUCCESS;
  213. }
  214.  
  215. #endif /* TEST */
  216.