Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TSR Unloading

257 views
Skip to first unread message

Marcus Gustafsson

unread,
Jan 29, 1997, 3:00:00 AM1/29/97
to

Hello everybody
How do you unload a TSR?
I've made a small TSR wich is supposed to remove itself the second time
its called, but I haven't got a clue how to do it, when I use dos
function 4c, everything just locks up.

-Marcus Gustafsson

George C. Lindauer

unread,
Jan 29, 1997, 3:00:00 AM1/29/97
to

Marcus Gustafsson (muad...@geocities.com) wrote:
: Hello everybody

You have to unhook all used interrupts, then use the memory deallocation
function on the PSP of the (TSR'd) version of the program. Also deallocate
the memory used by your tsr'd program's environment if you don't wish to
lose it. What I generally do is have the TSR hook an interrupt (say int 80h)
and then when you run it the second time it detects whether it is
previously loaded by examining the int 80h vector and maybe running it
to see if it can get a specific code back from the TSR'd version. Then
you unhook the ints, free the memory, and return to DOS. If you want you
can put the rundown code in the TSR'd version... then instead of
returning to DOS it should return to your second invocation of the
tsr which can then return to DOS.

David
:
: -Marcus Gustafsson

The Fool

unread,
Jan 30, 1997, 3:00:00 AM1/30/97
to


and don't forget to switch the the TSR's PSP if calling 4Ch int 21
otherwise you just kill the program which was active, as your TSR
came to execution again. Besides calling 4C in a TSR is not too wise.
Some systems can react very strangely.
The most safe way is to free all the handles, reset the interrupts used
and go through the MCB's to change all of the PSP entries equal to
yours to 0000. You should have saved the PSP at installation time.

--
Have a nice, foolish day,
THE FOOL

I THINK I'M GOING SLIGHTLY MAD ...

Nick Brown

unread,
Jan 30, 1997, 3:00:00 AM1/30/97
to

There's a convention that TSRs should hook interrupt 2Fh and respond to
this interrupt being called with a certain "magic" value in AX. You can
code your initials in ASCII or whatever. Extra elegance comes by having
this "multiplex code" be a command line option, so you can coexist
with another TSR which uses the same method and by coincidence the same
AX value.

------------------------------------------------------------------------
|\ | o _ |/ Life's like a jigsaw
| \| | |_ |\ You get the straight bits
But there's something missing in the middle
Nick Brown, Strasbourg, France (Nick....@dct.coe.fr)
------------------------------------------------------------------------

DONALD G. DAVIS

unread,
Jan 30, 1997, 3:00:00 AM1/30/97
to

Marcus Gustafsson <muad...@geocities.com> writes:

>Hello everybody
>How do you unload a TSR?
>I've made a small TSR wich is supposed to remove itself the second time
>its called, but I haven't got a clue how to do it, when I use dos
>function 4c, everything just locks up.

First, the transient code has to search for a resident copy, and
if found, store the segment address of the resident copy. I've seen this
done in three ways: (1) Search for a unique signature string in the
resident code. This can be an actual copyright notice, etc., or (to save
resident memory), a paragraph or two of the program's executable code
(provided that you make sure that no variables are in the signature).
(2) Hook a special interrupt (INT 2Fh and INT 2Dh are the most popular)
and have the resident copy's interrupt handler return a unique value if
it's called by the transient copy. (3) Search the memory control block
chain for a valid MCB containing the TSR's name in the owner field, and a
matching size in the size field. Option 1 is probably the easiest one to
do, and most economical of memory. Option 2 is probably the most
foolproof. Option 3 might be useful in special cases.

If a resident copy is found, when you attempt to uninstall, you
must do three things: (1) Call INT 21h, function 35h to get your
interrupt's address for every interrupt you've hooked. Compare the output
in BX with the offset of your interrupt handler; if not the same, a later
program has hooked that interrupt, and you must abort the uninstallation.
(2) If that test is passed, use INT 21h, function 25h to readdress each
interrupt to the original address which you should have stored in a
variable before going resident (this reverses what you did when you hooked
the interrupt). (3) Use INT 21h, function 49h, with the segment of the
resident copy in ES, to free the TSR's memory. (This should also be done
for its environment block, if you didn't release that before installing.)
If all this proceeds without errors, you can *then* terminate with
function 4Ch.

I can provide .ASM code samples of these techniques on request.

--Donald Davis


DONALD G. DAVIS

unread,
Jan 31, 1997, 3:00:00 AM1/31/97
to

>>Nick....@dct.coe.fr.nospam (Nick Brown) writes:

>There's a convention that TSRs should hook interrupt 2Fh and respond to
>this interrupt being called with a certain "magic" value in AX. You can
>code your initials in ASCII or whatever. Extra elegance comes by having
>this "multiplex code" be a command line option, so you can coexist
>with another TSR which uses the same method and by coincidence the same
>AX value.

That will work, but you don't really need to do this manually.
The TSR Pc-Dial (from the book "PC Magazine DOS 6 Techniques &
Utilities," by Jeff Prosise) incorporates a routine to find the first
unused multiplex ID number on the system running the TSR.

--Donald Davis

DONALD G. DAVIS

unread,
Jan 31, 1997, 3:00:00 AM1/31/97
to

The Fool <"The Fool"@Insanity.com> writes:

>and don't forget to switch the the TSR's PSP if calling 4Ch int 21
>otherwise you just kill the program which was active, as your TSR
>came to execution again. Besides calling 4C in a TSR is not too wise.
>Some systems can react very strangely.

I believe that the original questioner was calling INT 21, 4Ch
from the transient code when attempting to get the transient copy to
uninstall the resident copy. The above problem arises only if it is
called from the resident copy.
--Donald Davis

Barry Allard

unread,
Feb 3, 1997, 3:00:00 AM2/3/97
to

Marcus Gustafsson wrote:
>
> Hello everybody
> How do you unload a TSR?
> I've made a small TSR wich is supposed to remove itself the second time
> its called, but I haven't got a clue how to do it, when I use dos
> function 4c, everything just locks up.
>
> -Marcus Gustafsson

PC Intern from Abacus has a example of a TSR load/unload program.

Glenn

unread,
Feb 4, 1997, 3:00:00 AM2/4/97
to

The basic principles in unloading a TSR are:

1) Revector all hooked interrupts to their previous vectors but,
only if they still point to your code. If not, someone else
has hooked them after your TSR was loaded and it now cannot
be unloaded.

2) Restore anything else your TSR might have done, ie allocating
memory, changing Video Modes, reprogramming the timer, etc.

3) Free the memory allocated to your TSR (and the environment if
you kept it when the TSR was loaded). If the TSR is a .COM
then its PSP is the .Code segment. If its an .EXE, then you
have to save the PSP segment in a local variable when it loads.

Hope this helps.

0 new messages