Quote
swright...@aol.com wrote:
> I'd like to see the code that unloads a TSR.
Ok, heres the code for a prog that hooks onto
int 8, and unloads it selfe when run again.
You have to add some code that hooks onto int 2f
to do some better checking, but the unloader works.
Program Int8_ISR;
{ Hooks up to int 8, and unhooks when run again }
{$M $800,0,0 } { 2K stack, no heap }
{$R-,S-}
uses Dos;
var
Int8Save : pointer;
p_id: word;
count: word;
label ExitLabel;
{$F+}
procedure CloseDown;
begin
{ Restore vectors }
SetIntVec($8,Int8Save);
{ Closedown }
Writeln('Closing');
writeln(count);
{ remove TSR from memory }
asm
mov es, word ptr [p_id] { segment address of TSR }
mov ah, 49h { free memoryblock }
int 21h { do it }
end;
end;
procedure Int8Handler; Assembler;
asm
jmp @@start
dw 'IS', 'R8' { used to identify my ISR }
dw offset CloseDown { save address to closedown proc }
dw seg CloseDown
dw seg @data { save datasegment }
dw 0 { used to save PSP segment }
@@start:
{ save regs }
push ax
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
{ do stuff }
mov ax, seg @data { restore datasegment }
mov ds, ax
mov ax, $40
mov es, ax
mov di, $18
mov al, es:[di]
and al, 32
cmp al, 32
jne @@noaction
mov ax, $b800
mov es, ax
mov di, 3998
mov ah, 129
mov al, 219
xor es:[di], ax
@@noaction:
pushf { push flags to simulate int command}
call Int8Save { call saved ISR }
{ restore regs }
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
{ and exit the right way }
iret
end;
{$F-}
begin
GetIntVec($8,Int8Save);
asm
nop
nop
end;
asm
mov bx, word ptr [Int8Save]
mov ax, word ptr [Int8Save + 2]
mov es, ax
add bx, 2 { skip jmp instruction }
{ check for previous installation }
cmp word ptr es:[bx], 'IS'
jne @@not_inst
add bx, 2
cmp word ptr es:[bx], 'R8'
jne @@not_inst
add bx, 2
{ it's installed, get closedown proc address }
mov si, word ptr es:[bx] { get offset }
mov word ptr [@@1], si { store }
add bx, 2
mov ax, word ptr es:[bx] { get segment }
mov word ptr [@@1+2], ax { store }
add bx, 2
mov ax, word ptr es:[bx] { restore old datsegment }
mov ds, ax
add bx, 2
mov ax, word ptr es:[bx] { get old PSP segment }
mov word ptr [p_id], ax { store }
call dword ptr [@@1] { call the CloseDown proc }
jmp ExitLabel
@@1:
dd 0
@@not_inst:
end;
{ install }
asm
mov di, offset Int8Handler
mov ax, seg Int8Handler
mov es, ax
add di, 12 { skip other things }
push es { save }
mov ah, 62h
int 21h { get PSP segment (process id) }
mov es, bx
mov si, bx { save }
mov es, es:[2Ch] { dos enviroment }
mov ah, 49h { free memory }
int 21h { free dos env }
pop es { restore }
mov word ptr es:[di], si { save the PSP of the TSR }
end;
count:= 0;
SetIntVec($8,Addr(Int8Handler)); { set my ISR }
Keep(0); { and keep it }
ExitLabel:
end.
- Asbj?rn