Source file: /~heha/hsn/dos/uninst.zip/UNINST.PAS

{$A-,B-,D-,E-,F-,G-,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V+,X+}
unit UnInst;
{Unit zur Deinstallation von residenten PASCAL-Programmen}
{Installationscheck über Multiplexer-Interrupt 2F/0F/10}
{Remotes Dehooking über Multiplexer-Interrupt 2F/0F/11}
{*** Das PASCAL-Programm darf jedoch nicht selbst den Int2F anzapfen!***}

{Copyr. 1994 haftmann#software +++Freeware+++}
{Bugfix 11/00: JMP statt CALL zum OldInt2F (Fehler mit XFS)}

{Normales PASCAL-Programm dazu um folgende Zeilen erweitern:
 (*$M $800,0,0*)
 uses UnInst,Dos,..;
 var OldIntXX: procedure;	(*!!! So und nicht anders !!!*)
 ...
 procedure NewIntXX; interrupt;	(*Beispiel-Interrupt, XX durch Nummer*)
  begin				(*ersetzen!*)
   asm pushf end;
   OldIntXX;
   ...
  end;

 ...
 begin
  RegisterTSR($1234);		(*am Anfang mit zufälliger Zahl registrieren
		Die wirkliche Uniquität ist nicht ganz so wichtig,
		jedoch sollte die Zahl verändert werden:
		- bei jedem neuen Programmprojekt
		- bei Hinzunahme weiterer Interrupts im Projekt *)
  ...
  ...				(*weitere Parameterauswertung*)
  if ParamStr(1)='/u' then begin
   i:= RemoveTSR;		(*TSR entfernen (das ist alles!)*)
   case i of
    -1: writeln('TSR entfernt');
    -2: writeln('TSR nicht installiert - nichts zu entfernen');
    -3: writeln('Speicherfehler beim Deinstallieren');
   else writeln('Andere TSR stört, Interrupt ',i,' (dez!!) geklaut!');
   end;
  end else begin
  if Installed then writeln('Ich bin schon installiert')
  else begin
   ...
   GetIntVec($XX,@OldIntXX);
   SetIntVec($XX,@NewIntXX);
   ...				(*Interrupts wie üblich installieren*)
   writeln('Ich residiere');
   keep(0);
   end;
  end;}

interface
 uses dos;
 procedure RegisterTSR(REQcode: Word);  {einfach am Anfang aufrufen}
 function Installed: Boolean;	{true wenn installiert, sonst false}
 function RemoveTSR: Integer;	{-1 wenn ok, -2 wenn nicht installiert,
				IntNo, der 1. gehookte Interruptvektor
				-3 bei Speicherfehler}
 procedure SetIntVec(IntNo:Byte; Vector:Pointer); {max. 8mal aufrufen!}
 procedure Keep(ExitCode: Word);
			{überschreiben die Unit-DOS-Standardprozeduren}
implementation

const REQfunc=$0f10;
      ANScode=$7f90;
      UNIfunc=$0f11;

function daten:integer; assembler;	{Datenspeicher im Codesegment}
 asm
  dw 0		;{0 - PSP-Adresse beim Registrieren}
  dw $12aa	;{2 - Registrier-Nummer, Default bei fehlender Registrierung}
  dd 0		;{4 - OldInt2F}
  db 0		;{8 - Anzahl Vektoren}
  db 0		;{9 - für 8 Interruptvektoren Platz}
  dd 0,0	;{1 Byte IntNo, 1 dword OldIntVec, 1 dword NewIntVec}
  db 0
  dd 0,0
  db 0
  dd 0,0
  db 0
  dd 0,0
  db 0
  dd 0,0
  db 0
  dd 0,0
  db 0
  dd 0,0
  db 0
  dd 0,0
 end;

function UnInstall:integer; forward;	{Assembler ruhigstellen}

procedure NewInt2F; assembler;
 asm
  pushf
  cmp dx,cs:[offset daten+2]
  jnz @@1
  cmp ax,REQfunc
  jnz @@2
  mov ax,ANScode
@@3:
  mov dx,cs:[offset daten+0]		;{PSP-Adresse}
  popf
  iret
@@2:
  cmp ax,UNIfunc
  jnz @@1
  push bx
  push cx
  push dx
  push ds
  push es
  call UnInstall
  pop es
  pop ds
  pop dx
  pop cx
  pop bx
  jmp @@3
@@1:
  popf
  jmp cs:dword [offset daten+4]
 end;

function UnInstall:integer; assembler;
 asm
   cld
   mov si,offset daten+8
   segcs lodsb
   cbw
   xchg cx,ax
   jcxz @@ok
@@1:
   segcs lodsb
   mov ah,35h
   int 21h	;{GetIntVec}
   cmp bx,cs:[si+4]
   jnz @@err
   mov bx,es
   cmp bx,cs:[si+6]
   jnz @@err
   add si,8
   loop @@1
   mov si,offset daten+8
   segcs lodsb
   cbw
   xchg cx,ax
@@2:
   segcs lodsb
   mov ah,25h
   lds dx,cs:[si]
   int 21h	;{SetIntVec}
   add si,8
   loop @@2
@@ok:
   mov ax,-1
   jmp @@exi
@@err:
   xor ah,ah	;{AL=Interrupt-Nummer}
@@exi:
 end;

procedure RegisterTSR; assembler;
 asm
  mov ax,REQcode
  mov cs:[offset daten+2],ax
  mov ah,62h		;{Get PSP Addr}
  int 21h
  mov cs:[offset daten+0],bx
 end;

function Installed; assembler;
 asm
  mov ax,REQfunc
  mov dx,cs:[offset daten+2]
  int 2fh
  cmp ax,ANScode
  mov ax,true
  jz @@1
  mov ax,false
@@1:
 end;

function RemoveTSR; assembler;
 asm
  call Installed
  mov ax,-2
  jnz @@1		;{exit}
  mov ax,UNIfunc
  mov dx,cs:[offset daten+2]
  int 2fh		;{Dehooking, AX=Ergebnis, DX=PSP-Adresse}
  cmp ax,-1
  jnz @@1		;{Fehler}
  mov es,dx
  mov ah,49h
  int 21h
  mov ax,-3		;{Speicherzuordnungsfehler}
  jc @@1
  mov ax,-1
@@1:
 end;

procedure SetIntVec;	{max. 8mal aufrufbar!!!}
 begin
  asm
   mov si,offset daten+8
   cld
   segcs lodsb
   mov ah,9		;{9 Bytes pro Feld}
   mul ah
   add si,ax
   mov al,IntNo
   mov cs:[si],al
   mov ah,35h
   int 21h
   mov cs:[si+1],bx
   mov cs:[si+3],es
   les bx,Vector
   mov cs:[si+5],bx
   mov cs:[si+7],es
   inc cs:[byte ptr daten+8]
  end;
  Dos.SetIntVec(IntNo,Vector);
 end;

procedure Keep;
 begin
  asm
   mov ax,352Fh		;{GetIntVec(2f)}
   int 21h
   mov cs:[offset daten+4],bx
   mov cs:[offset daten+6],es
   mov es,cs:[offset daten+0]
   mov es,es:[2ch]	;{Environment freigeben}
   mov ah,49h
   int 21h
  end;
  UnInst.SetIntVec($2F,@NewInt2F);	{das neue mit Registrierung}
  Dos.Keep(ExitCode);
 end;

begin
end.
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded