Exemple de programme d’arrêt-and-Stay-Resident (TSR)

Exclusion de responsabilité du contenu obsolète de la base de connaissances

Cet article a été rédigé sur les produits pour lesquels Microsoft n’offre plus aucune prise en charge. Par conséquent, cet article est proposé « en l’état » et ne sera plus mis à jour.

Résumé

L’exemple de code suivant illustre l’utilisation de Microsoft C à écrire un programme résident (TSR). L’exemple illustre également l’utilisation des fonctions suivantes de la bibliothèque d’exécution C :
   _dos_setvect   _dos_getvect
_dos_keep
_chain_intr
spawnXXX

Plus d'informations

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 */
}

Propriétés

ID d'article : 3999064 - Dernière mise à jour : 27 janv. 2017 - Révision : 1

Commentaires