home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / IVDETECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  9.0 KB  |  283 lines

  1. /**
  2. *
  3. * Name        ivdetect -- Detect an installed intervention function
  4. *                even if it is partially covered.
  5. *
  6. * Synopsis    ercode = ivdetect(pvectors,pident,ppctrl,pmask);
  7. *
  8. *        int ercode      Success code:
  9. *                    IV_NO_ERROR if successful and
  10. *                      found function is removable;
  11. *                    IV_NOT_FOUND if not found;
  12. *                    IV_PART_COVERED if found but
  13. *                      some vectors specified in b_ivmask
  14. *                      are covered by another ISR.
  15. *
  16. *        const IV_VECTORS far *pvectors
  17. *                  Address of structure containing
  18. *                  a set of interrupt vectors to examine.
  19. *        const char far *pident
  20. *                  Pointer to array of 16 bytes of
  21. *                  identifying information.
  22. *        IV_CTRL far **ppctrl
  23. *                  Address of far pointer in which to
  24. *                  return address of intervention control
  25. *                  block of the found function, or FARNIL
  26. *                  if the function is not found.
  27. *        unsigned far *pmask
  28. *                  Address in which to return bit mask
  29. *                  indicating the vectors served by
  30. *                  the found intervention function that
  31. *                  are exposed.    The following bits are
  32. *                  used:
  33. *
  34. *                 IV_F_TIMER      INT 08h:  Timer tick.
  35. *                 IV_F_KEYSTROKE  INT 09h:  Keystroke.
  36. *                 IV_F_DISK         INT 13h:  BIOS disk services.
  37. *                 IV_F_DOS         INT 21h:  DOS functions.
  38. *                 IV_F_IDLE         INT 28h:  DOS idle.
  39. *                 IV_F_2COM         INT 0ch:  Comm port 1
  40. *                 IV_F_1COM         INT 0bh:  Comm port 2
  41. *
  42. * Description    This function examines the contents of memory pointed to
  43. *        by a set of interrupt vectors to see whether it contains
  44. *        a particular intervention control block.  If so, the
  45. *        function returns the address of the control block; if
  46. *        not, the function returns FARNIL.
  47. *
  48. *        The contents of the control block contain the
  49. *        information required to disable the intervention
  50. *        function and to remove the program containing it.
  51. *
  52. *        This function assumes that the intervention filters were
  53. *        the most recently installed handlers for their
  54. *        respective interrupts.    This function does NOT trace
  55. *        chains of "cascaded" interrupt handlers.  However, it
  56. *        can locate the intervention control block even if some
  57. *        of the intervention filters are obscured by other ISRs.
  58. *        It returns a mask indicating which filters are "exposed"
  59. *        and hence directly removable.
  60. *
  61. *        The global variable b_ivmask governs whether the
  62. *        intervention control block is deemed removable.  The
  63. *        block is removable (and ercode is IV_NO_ERROR) only if
  64. *        all of the filters indicated by bits in b_ivmask are
  65. *        "exposed".  However, all the interrupt vectors that may
  66. *        be used by intervention code are checked regardless of
  67. *        whether they are specified in b_ivmask, and the results
  68. *        of the test are returned in *pmask.
  69. *
  70. * Returns    ercode          Success code.
  71. *        *ppctrl       Far pointer to the intervention control
  72. *                    block of the found function, or FARNIL
  73. *                    if the function is not found.
  74. *        *pmask          Bit mask indicating the exposed vectors
  75. *                    served by the found intervention
  76. *                    function.  The following bits are used:
  77. *
  78. *                 IV_F_TIMER      INT 08h:  Timer tick.
  79. *                 IV_F_KEYSTROKE  INT 09h:  Keystroke.
  80. *                 IV_F_DISK         INT 13h:  BIOS disk services.
  81. *                 IV_F_DOS         INT 21h:  DOS functions.
  82. *                 IV_F_IDLE         INT 28h:  DOS idle.
  83. *                 IV_F_2COM         INT 0ch:  Comm port 1
  84. *                 IV_F_1COM         INT 0bh:  Comm port 2
  85. *
  86. * Version    6.00 (C)Copyright Blaise Computing Inc. 1989
  87. *
  88. **/
  89.  
  90. #include <dos.h>
  91. #include <string.h>
  92.  
  93. #include <binterv.h>
  94. #include <butil.h>
  95.  
  96.                       /* Internal functions.          */
  97. static IV_CTRL far *check_vec(const void far *);
  98. static int match_vec(const IV_CTRL far *,
  99.              const char        *);
  100.  
  101. int ivdetect(pvectors,pident,ppctrl,pmask)
  102. const IV_VECTORS far *pvectors;
  103. const char     far *pident;
  104. IV_CTRL     far **ppctrl;
  105. unsigned     far *pmask;
  106. {
  107.     const unsigned masks[] =          /* Array of mask values.          */
  108.     {                      /* These must correspond with   */
  109.                       /*  the contents of pvecs[]!    */
  110.     IV_F_TIMER,
  111.     IV_F_KEYSTROKE,
  112.     IV_F_DISK,
  113.     IV_F_DOS,
  114.     IV_F_IDLE,
  115.     IV_F_1COM,
  116.     IV_F_2COM,
  117.     };
  118.  
  119. #define NUM_VECTORS (sizeof(masks)/sizeof(masks[0]))
  120.  
  121.     const void far *pvecs[NUM_VECTORS];
  122.     IV_CTRL    far *ptest[NUM_VECTORS];
  123.     char        ident[sizeof((*ppctrl)->ident)];
  124.     int         i,first_match,result;
  125.  
  126.     pvecs[0] = pvectors->ptimer;      /* pvecs[] is used to make the  */
  127.     pvecs[1] = pvectors->pkeybd;      /*  main loop more convenient.  */
  128.     pvecs[2] = pvectors->pdisk;       /*  Sequence of items must      */
  129.     pvecs[3] = pvectors->pdos;          /*  correspond with masks[]!    */
  130.     pvecs[4] = pvectors->pidle;
  131.     pvecs[5] = pvectors->pcom1;
  132.     pvecs[6] = pvectors->pcom2;
  133.  
  134.     utpeekn(pident,ident,sizeof(ident));    /* Local copy of          */
  135.                         /*    identification string.*/
  136.  
  137.     *pmask    = 0;
  138.     first_match = -1;
  139.     for (i = 0; i < NUM_VECTORS; i++)     /* Examine all vectors.      */
  140.     {
  141.     ptest[i] = check_vec(pvecs[i]);  /* Fetch address of possible */
  142.                      /*  control block.          */
  143.  
  144.     if (match_vec(ptest[i],ident))     /* Check control block.      */
  145.     {
  146.         if (first_match < 0)
  147.         first_match = i;
  148.                      /* Must equal other found    */
  149.                      /*  blocks.              */
  150.         if (ptest[i] == ptest[first_match])
  151.         *pmask |= masks[i];     /* Have found a total match. */
  152.     }
  153.     }
  154.  
  155.     if (first_match >= 0)
  156.     {
  157.     *ppctrl = ptest[first_match]; /* Found a control block.       */
  158.  
  159.                       /* See whether enough filters   */
  160.                       /*  are exposed.              */
  161.     if ((*pmask & b_ivmask) == b_ivmask)
  162.         result = IV_NO_ERROR;
  163.     else
  164.         result = IV_PART_COVERED;
  165.     }
  166.     else
  167.     {
  168.     *ppctrl = FARNIL;
  169.     result    = IV_NOT_FOUND;
  170.     }
  171.  
  172.     return result;
  173. }
  174.  
  175. /**
  176. *
  177. * Name        check_vec -- Return pointer to IV_CTRL structure (if any)
  178. *                 used by an intervention filter.
  179. *
  180. * Synopsis    presult = check_vec(ptr);
  181. *
  182. *        IV_CTRL far *presult
  183. *                  Far pointer to possible IV_CTRL
  184. *                  structure, or FARNIL if ptr or the
  185. *                  data pointed to is invalid.
  186. *        void far *ptr      Address of entry point of purported
  187. *                  filter.
  188. *
  189. * Description    This function examines the contents of memory pointed to
  190. *        by an interrupt vector to see whether it might be an
  191. *        entry point to a Blaise C TOOLS intervention filter.  The
  192. *        resulting value is checked so that it can be used as a
  193. *        pointer to an IV_CTRL structure without fear that
  194. *        segment boundaries may be crossed.
  195. *
  196. *        By convention, intervention filters begin with a two-byte
  197. *        jump instruction followed by a two-byte pointer to their
  198. *        intervention control block.
  199. *
  200. *        This function does NOT trace chains of "cascaded"
  201. *        interrupt handlers.
  202. *
  203. * Returns    presult       Far pointer to possible IV_CTRL
  204. *                  structure, or FARNIL if ptr or the
  205. *                  data pointed to is invalid.
  206. *
  207. **/
  208.  
  209. static IV_CTRL far *check_vec(ptr)
  210. const void far *ptr;
  211. {
  212.     unsigned int offset;          /* Scratch variable:  offset    */
  213.                       /* within segment.          */
  214.  
  215.     offset = utoff(ptr);
  216.  
  217.     if (offset >= 0xfffd)          /* Make sure that the two-byte  */
  218.     return FARNIL;              /* pointer to the control       */
  219.                       /* block doesn't straddle a     */
  220.                       /* segment boundary.          */
  221.  
  222.                       /* Extract offset of control    */
  223.                       /* block.               */
  224.     offset = utpeekw(uttofaru(utseg(ptr),offset+2));
  225.  
  226.     /* Make sure that the control block does not straddle a segment   */
  227.     /* boundary.  Notice that this computation requires that          */
  228.     /* sizeof(IV_CTRL) be at least 2 (which it is).              */
  229.  
  230.     if (offset >= (unsigned) 0xffff - sizeof(IV_CTRL) + 2)
  231.     return FARNIL;
  232.  
  233.     return uttofar(utseg(ptr),offset,IV_CTRL);
  234. }
  235.  
  236. /**
  237. *
  238. * Name        match_vec -- Check validity of potential address of
  239. *                 intervention control block.
  240. *
  241. * Synopsis    match = match_vec(ptr,pident);
  242. *
  243. *        int match      Zero if not a valid intervention
  244. *                    control block or if identification
  245. *                    string fails to match,
  246. *                  Nonzero if valid and matching.
  247. *        const IV_CTRL far *ptr
  248. *                  Purported address of intervention
  249. *                    control block.
  250. *        const char *pident
  251. *                  Pointer to array of 16 bytes of
  252. *                    identifying information
  253. *
  254. * Description    This function examines a pointer to see whether whether
  255. *        it might contain the address of an intervention control
  256. *        block.
  257. *
  258. * Returns    match          Zero if not a valid intervention
  259. *                    control block or if identification
  260. *                    string fails to match,
  261. *                  Nonzero if valid and matching.
  262. *
  263. **/
  264.  
  265. static int match_vec(ptr,pident)
  266. const IV_CTRL far *ptr;
  267. const char      *pident;
  268. {
  269.     char scratch[sizeof(ptr->ident)];
  270.  
  271.     if (   ptr == FARNIL
  272.     || ptr->signature !=   (unsigned int) IV_SIGNATURE
  273.     || ptr->sign2      != ~ (unsigned int) IV_SIGNATURE)
  274.     return 0;
  275.  
  276.                   /* Make local copy of identifying       */
  277.                   /* string from control block.          */
  278.     utpeekn(ptr->ident,scratch,sizeof(scratch));
  279.  
  280.                   /* Return 1 if match.              */
  281.     return (0 == memcmp(scratch,pident,sizeof(scratch)));
  282. }
  283.