Terminate-and-Stay-Resident (TSR) Program Example

Isenção de Responsabilidade para Conteúdo da KB Desativado

Este artigo foi escrito sobre produtos para os quais a Microsoft já não fornece suporte. Por conseguinte, este artigo é oferecido "tal como está" e não será mais atualizado.

Summary

The following code example demonstrates using Microsoft C to write a terminate-and-stay-resident (TSR) program. The example also demonstrates using the following functions in the C run-time library:
   _dos_setvect
_dos_getvect
_dos_keep
_chain_intr
spawnXXX

More Information

DIRZAP.MAK
----------

DIRZAP.OBJ: DIRZAP.C
CL -AM -c DIRZAP.C
LINK DIRZAP.OBJ;

DIRZAP.H
--------

/********************************************************************/
/* */
/* DirZap.h */
/* */
/* This header file defines a global variable, macros, */
/* function pointers, and function prototypes needed */
/* in the DirZap.c program. */
/* */
/* */
/********************************************************************/

/* Global Variable For Macro SHIFTL(x, n) */
long _ADDRESS;

/* Macro Definitions */
#define INT5 0x5
#define INT21 0x21
#define SHIFTL(x, n) (_ADDRESS = 0L, _ADDRESS = (long)(x), _ADDRESS << (n))
#define HIBYTE(x) (((unsigned)(x) >> 8) & 0xff)
#define REGPAK unsigned es, unsigned ds, unsigned di, unsigned si,\
unsigned bp, unsigned sp, unsigned bx, unsigned dx,\
unsigned cx, unsigned ax, unsigned ip, unsigned cs,\
unsigned flags

/* Function Pointers */
void (interrupt far *save_dir_adr)();
/* Saves address of the original interrupt service routine */

void (interrupt far *set_dir_adr)();
/* This function pointer gets set to the address of the new
interrupt service routine 'set_dir' */

void (interrupt far *reset_dir_adr)();
/* This function pointer gets set to the address of the new
interrupt service routine 'reset_dir' */

/* Function Declarations */
void cdecl interrupt far set_dir(REGPAK);
/* This is the new service routine which zaps the directory
interrupt routines. */

void interrupt far reset_dir(void);
/* This routine toggles between setting and disabling the
directory interrupt routines */

unsigned _get_memsize(void);
/* This function gets the number of bytes to keep resident */

short _set_shell(void);
/* Sets a DOS shell. */

DIRZAP.C
--------

/*******************************************************************/
/* */
/* DirZap.c */
/* */
/* This is an illustration of a Terminate-and-Stay-Resident */
/* program. It traps and disables the directory interrupts for */
/* MkDir, RmDir, and ChDir. When DirZap is in memory you can */
/* toggle it on and off with the PrintScreen key. When it is */
/* on you will not be able to change directories or make or */
/* remove any directories. */
/* The PrintScreen key and directories have nothing to do with */
/* TSR programming. They were just randomly picked to create */
/* an application. This program is not intended to be a complete */
/* application. It's intent is to demonstrate how to write a */
/* TSR. You can take the concept used here and incorporate it */
/* in to your own program. */
/* Below is a summary of what this program does : */
/* - Save the address of INT 21 */
/* - Revector INT 21 to a routine that disables the directory */
/* operations. */
/* - Revector the PrintScreen interrupt to a routine that will */
/* toggle DirZap on and off. */
/* - Execute a _dos_keep to make the program resident */
/* */
/* */
/* Copyright (c) Microsoft Corp 1988. All rights reserved. */
/* */
/* To run: */
/* 1) Type DirZap at dos prompt */
/* 2) The PRINT SCREEN key now toggles */
/* DirZap on and off but no memory */
/* is freed. */
/* */
/*******************************************************************/
/* NOTE: */
/* */
/* THIS PROGRAM, ITS USE, OPERATION AND SUPPORT IS PROVIDED "AS IS"*/
/* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, */
/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
/* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THIS */
/* PROGRAM IS WITH THE USER. IN NO EVENT SHALL MICROSOFT BE LIABLE */
/* FOR ANY DAMAGES INCLUDING, WITHOUT LIMITATION, ANY LOST */
/* PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR CONSEQUENTIAL */
/* DAMAGES ARISING THE USE OR INABILITY TO USE SUCH PROGRAM, EVEN */
/* IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES*/
/* OR FOR ANY CLAIM BY ANY OTHER PARTY. */
/*******************************************************************/

#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include "dirzap.h"

extern unsigned _psp; /* _psp = segment address of PSP */
unsigned far *psp_pointer; /* To retrieve the memsize to stay */
/* resident */
short hot_key=1; /* To toggle dirzap on and off */

void main(void)
{

/***************************************/
/* */
/* Revector the directory interrupts */
/* */
/***************************************/
save_dir_adr = _dos_getvect(INT21); /* Save original address */
set_dir_adr = set_dir; /* Get addr of new routine */

/***************************************/
/* */
/* Revector the PRINT SCREEN interrupt */
/* */
/***************************************/
reset_dir_adr = reset_dir; /* Get addr of new routine*/
_dos_setvect (INT5, reset_dir_adr); /* Revector to new routine*/


/***************************************/
/* */
/* Become memory resident. */
/* */
/***************************************/
_dos_keep(0, _get_memsize());

printf ("DirZap is now memory resident"); /* Inform the user */

}

void cdecl interrupt far set_dir(REGPAK)
{
/********************************************************************/
/* */
/* DS:DX points to the string entered by the user for MkDir, RmDir */
/* and ChDir. This function makes that string null so that */
/* the user will no longer be able to make, remove, or change */
/* directories. */
/* WARNING: When compiled at high warning levels, several warnings */
/* are generated. This is because several elements of REGPAK are */
/* not referenced. These warnings should be ignored. */
/* */
/********************************************************************/

if (HIBYTE(ax) == 0x39 || HIBYTE(ax) == 0x3A || HIBYTE(ax) == 0x3B)
dx=0;
_chain_intr(save_dir_adr);
}

void interrupt far reset_dir()
{
/****************************************************************/
/* */
/* This function is used to toggle DirZap on and off. */
/* */
/****************************************************************/

if (hot_key)
{
hot_key=0;
_dos_setvect(INT21, save_dir_adr); /* Reset initial vector */
}
else
{
hot_key=1;
_dos_setvect(INT21, set_dir_adr); /* Install DirZap again */
_chain_intr(set_dir_adr); /* Chain to the Zapper function */
}
}

unsigned _get_memsize()
{
psp_pointer = (int far *) SHIFTL(_psp, 16); /* Get segment of the*/
/* PSP */
return(psp_pointer[1] - _psp); /* Amount of memory to */
/* stay resident */
}
Propriedades

ID do Artigo: 3999064 - Última Revisão: 1 de dez de 2003 - Revisão: 1

Comentários