home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name ivdetect -- Detect an installed intervention function
- * even if it is partially covered.
- *
- * Synopsis ercode = ivdetect(pvectors,pident,ppctrl,pmask);
- *
- * int ercode Success code:
- * IV_NO_ERROR if successful and
- * found function is removable;
- * IV_NOT_FOUND if not found;
- * IV_PART_COVERED if found but
- * some vectors specified in b_ivmask
- * are covered by another ISR.
- *
- * const IV_VECTORS far *pvectors
- * Address of structure containing
- * a set of interrupt vectors to examine.
- * const char far *pident
- * Pointer to array of 16 bytes of
- * identifying information.
- * IV_CTRL far **ppctrl
- * Address of far pointer in which to
- * return address of intervention control
- * block of the found function, or FARNIL
- * if the function is not found.
- * unsigned far *pmask
- * Address in which to return bit mask
- * indicating the vectors served by
- * the found intervention function that
- * are exposed. The following bits are
- * used:
- *
- * IV_F_TIMER INT 08h: Timer tick.
- * IV_F_KEYSTROKE INT 09h: Keystroke.
- * IV_F_DISK INT 13h: BIOS disk services.
- * IV_F_DOS INT 21h: DOS functions.
- * IV_F_IDLE INT 28h: DOS idle.
- * IV_F_2COM INT 0ch: Comm port 1
- * IV_F_1COM INT 0bh: Comm port 2
- *
- * Description This function examines the contents of memory pointed to
- * by a set of interrupt vectors to see whether it contains
- * a particular intervention control block. If so, the
- * function returns the address of the control block; if
- * not, the function returns FARNIL.
- *
- * The contents of the control block contain the
- * information required to disable the intervention
- * function and to remove the program containing it.
- *
- * This function assumes that the intervention filters were
- * the most recently installed handlers for their
- * respective interrupts. This function does NOT trace
- * chains of "cascaded" interrupt handlers. However, it
- * can locate the intervention control block even if some
- * of the intervention filters are obscured by other ISRs.
- * It returns a mask indicating which filters are "exposed"
- * and hence directly removable.
- *
- * The global variable b_ivmask governs whether the
- * intervention control block is deemed removable. The
- * block is removable (and ercode is IV_NO_ERROR) only if
- * all of the filters indicated by bits in b_ivmask are
- * "exposed". However, all the interrupt vectors that may
- * be used by intervention code are checked regardless of
- * whether they are specified in b_ivmask, and the results
- * of the test are returned in *pmask.
- *
- * Returns ercode Success code.
- * *ppctrl Far pointer to the intervention control
- * block of the found function, or FARNIL
- * if the function is not found.
- * *pmask Bit mask indicating the exposed vectors
- * served by the found intervention
- * function. The following bits are used:
- *
- * IV_F_TIMER INT 08h: Timer tick.
- * IV_F_KEYSTROKE INT 09h: Keystroke.
- * IV_F_DISK INT 13h: BIOS disk services.
- * IV_F_DOS INT 21h: DOS functions.
- * IV_F_IDLE INT 28h: DOS idle.
- * IV_F_2COM INT 0ch: Comm port 1
- * IV_F_1COM INT 0bh: Comm port 2
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1989
- *
- **/
-
- #include <dos.h>
- #include <string.h>
-
- #include <binterv.h>
- #include <butil.h>
-
- /* Internal functions. */
- static IV_CTRL far *check_vec(const void far *);
- static int match_vec(const IV_CTRL far *,
- const char *);
-
- int ivdetect(pvectors,pident,ppctrl,pmask)
- const IV_VECTORS far *pvectors;
- const char far *pident;
- IV_CTRL far **ppctrl;
- unsigned far *pmask;
- {
- const unsigned masks[] = /* Array of mask values. */
- { /* These must correspond with */
- /* the contents of pvecs[]! */
- IV_F_TIMER,
- IV_F_KEYSTROKE,
- IV_F_DISK,
- IV_F_DOS,
- IV_F_IDLE,
- IV_F_1COM,
- IV_F_2COM,
- };
-
- #define NUM_VECTORS (sizeof(masks)/sizeof(masks[0]))
-
- const void far *pvecs[NUM_VECTORS];
- IV_CTRL far *ptest[NUM_VECTORS];
- char ident[sizeof((*ppctrl)->ident)];
- int i,first_match,result;
-
- pvecs[0] = pvectors->ptimer; /* pvecs[] is used to make the */
- pvecs[1] = pvectors->pkeybd; /* main loop more convenient. */
- pvecs[2] = pvectors->pdisk; /* Sequence of items must */
- pvecs[3] = pvectors->pdos; /* correspond with masks[]! */
- pvecs[4] = pvectors->pidle;
- pvecs[5] = pvectors->pcom1;
- pvecs[6] = pvectors->pcom2;
-
- utpeekn(pident,ident,sizeof(ident)); /* Local copy of */
- /* identification string.*/
-
- *pmask = 0;
- first_match = -1;
- for (i = 0; i < NUM_VECTORS; i++) /* Examine all vectors. */
- {
- ptest[i] = check_vec(pvecs[i]); /* Fetch address of possible */
- /* control block. */
-
- if (match_vec(ptest[i],ident)) /* Check control block. */
- {
- if (first_match < 0)
- first_match = i;
- /* Must equal other found */
- /* blocks. */
- if (ptest[i] == ptest[first_match])
- *pmask |= masks[i]; /* Have found a total match. */
- }
- }
-
- if (first_match >= 0)
- {
- *ppctrl = ptest[first_match]; /* Found a control block. */
-
- /* See whether enough filters */
- /* are exposed. */
- if ((*pmask & b_ivmask) == b_ivmask)
- result = IV_NO_ERROR;
- else
- result = IV_PART_COVERED;
- }
- else
- {
- *ppctrl = FARNIL;
- result = IV_NOT_FOUND;
- }
-
- return result;
- }
-
- /**
- *
- * Name check_vec -- Return pointer to IV_CTRL structure (if any)
- * used by an intervention filter.
- *
- * Synopsis presult = check_vec(ptr);
- *
- * IV_CTRL far *presult
- * Far pointer to possible IV_CTRL
- * structure, or FARNIL if ptr or the
- * data pointed to is invalid.
- * void far *ptr Address of entry point of purported
- * filter.
- *
- * Description This function examines the contents of memory pointed to
- * by an interrupt vector to see whether it might be an
- * entry point to a Blaise C TOOLS intervention filter. The
- * resulting value is checked so that it can be used as a
- * pointer to an IV_CTRL structure without fear that
- * segment boundaries may be crossed.
- *
- * By convention, intervention filters begin with a two-byte
- * jump instruction followed by a two-byte pointer to their
- * intervention control block.
- *
- * This function does NOT trace chains of "cascaded"
- * interrupt handlers.
- *
- * Returns presult Far pointer to possible IV_CTRL
- * structure, or FARNIL if ptr or the
- * data pointed to is invalid.
- *
- **/
-
- static IV_CTRL far *check_vec(ptr)
- const void far *ptr;
- {
- unsigned int offset; /* Scratch variable: offset */
- /* within segment. */
-
- offset = utoff(ptr);
-
- if (offset >= 0xfffd) /* Make sure that the two-byte */
- return FARNIL; /* pointer to the control */
- /* block doesn't straddle a */
- /* segment boundary. */
-
- /* Extract offset of control */
- /* block. */
- offset = utpeekw(uttofaru(utseg(ptr),offset+2));
-
- /* Make sure that the control block does not straddle a segment */
- /* boundary. Notice that this computation requires that */
- /* sizeof(IV_CTRL) be at least 2 (which it is). */
-
- if (offset >= (unsigned) 0xffff - sizeof(IV_CTRL) + 2)
- return FARNIL;
-
- return uttofar(utseg(ptr),offset,IV_CTRL);
- }
-
- /**
- *
- * Name match_vec -- Check validity of potential address of
- * intervention control block.
- *
- * Synopsis match = match_vec(ptr,pident);
- *
- * int match Zero if not a valid intervention
- * control block or if identification
- * string fails to match,
- * Nonzero if valid and matching.
- * const IV_CTRL far *ptr
- * Purported address of intervention
- * control block.
- * const char *pident
- * Pointer to array of 16 bytes of
- * identifying information
- *
- * Description This function examines a pointer to see whether whether
- * it might contain the address of an intervention control
- * block.
- *
- * Returns match Zero if not a valid intervention
- * control block or if identification
- * string fails to match,
- * Nonzero if valid and matching.
- *
- **/
-
- static int match_vec(ptr,pident)
- const IV_CTRL far *ptr;
- const char *pident;
- {
- char scratch[sizeof(ptr->ident)];
-
- if ( ptr == FARNIL
- || ptr->signature != (unsigned int) IV_SIGNATURE
- || ptr->sign2 != ~ (unsigned int) IV_SIGNATURE)
- return 0;
-
- /* Make local copy of identifying */
- /* string from control block. */
- utpeekn(ptr->ident,scratch,sizeof(scratch));
-
- /* Return 1 if match. */
- return (0 == memcmp(scratch,pident,sizeof(scratch)));
- }