home *** CD-ROM | disk | FTP | other *** search
- {$R-,S-,I+,D+,T+,F-,V-,B-,N-,L+ }
- Unit Unhook;
-
- { Copyright (c)1988 Ross Neilson Wentworth }
- { Serendipity Software }
- { 1422 Elkgrove Circle, #3 }
- { Venice, CA 90291 }
- { All Rights Reserved }
-
- { This unit provides almost everything that is necessary to remove a }
- { resident program from memory. Examine the provided example NODICE }
- { to see how easy it is to use. }
-
- Interface
-
- Uses Dos;
-
- Function Installed(MultId : Byte) : Boolean;
-
- { Returns true if the resident program with the matching I.D. is loaded. }
-
- Function OkToRemove(MultID : Byte) : Boolean;
-
- { Returns true if it is safe to unload the resident }
- { program with the matching I.D. number. }
-
- Procedure RemoveProgram(MultID : Byte);
-
- { Removes the program with the matching I.D. from memory. }
-
- Implementation
-
- Type
- VectorTable = Record
- Number : Byte;
- OldInt : Pointer;
- Offset : Word;
- End;
- VectorArray = Array[1..2] of VectorTable;
- VectorPtr = ^VectorArray;
-
- Function DosVersion : Word;
-
- { Returns the DOS version as a word. It swaps the two bytes }
- { to make test more logical, i.e. DosVersion < $0300 }
-
- InLine($B4/$30/ { mov ah,30h }
- $CD/$21/ { int 21h }
- $86/$E0); { xchg ah,al }
-
- Function CheckSignature(MultId : Byte) : Byte;
-
- { Returns the popup's code segment }
-
- InLine($58/ { pop ax }
- $88/$C4/ { mov ah,al }
- $B0/$00/ { mov al,0 }
- $CD/$2F); { int 2Fh }
-
- Function GetTable(MultId : Byte) : Pointer;
-
- { Returns a pointer to the vector table }
-
- InLine($58/ { pop ax }
- $88/$C4/ { mov ah,al }
- $B0/$01/ { mov al,1 }
- $CD/$2F); { int 2Fh }
-
- Function GetCseg(MultId : Byte) : Word;
-
- { Returns the popup's code segment }
-
- InLine($58/ { pop ax }
- $88/$C4/ { mov ah,al }
- $B0/$02/ { mov al,2 }
- $CD/$2F); { int 2Fh }
-
- Procedure ReleaseMemory(MultId : Byte);
-
- { Releases the popup's memory }
-
- InLine($58/ { pop ax }
- $88/$C4/ { mov ah,al }
- $B0/$03/ { mov al,3 }
- $CD/$2F); { int 2Fh }
-
- Function Installed(MultID : Byte) : Boolean;
-
- Var
- TempV : Pointer;
-
- Begin
- Installed := False;
- If DosVersion < $0300 Then
- Begin { DOS 2.x }
- GetIntVec($2F,TempV);
- If TempV = Nil Then Exit;
- End;
- If CheckSignature(MultId) = $FF Then Installed := True;
- End;
-
- Function OkToRemove(MultID : Byte) : Boolean;
-
- Var
- OldVector : Pointer;
- NewVector : Pointer;
- Index : Integer;
- PopCSeg : Word;
- Table : VectorPtr;
-
- Begin
- Table := GetTable(MultId);
- Index := 1;
- OkToRemove := False;
- PopCSeg := GetCSeg(MultId);
- While Table^[Index].Number <> 0 Do
-
- { compares the current value of the interrupt vector with what the }
- { resident program set it to. If ALL of them are unchanged then it }
- { is safe to remove the program from memory. }
-
- Begin
- GetIntVec(Table^[Index].Number,NewVector);
- OldVector := Ptr(PopCSeg,Table^[Index].Offset);
- If OldVector <> NewVector Then Exit;
- Inc(Index);
- End;
- OkToRemove := True;
- End;
-
- Procedure RemoveProgram(MultID : Byte);
-
- Var
- Index : Integer;
- Table : VectorPtr;
-
- Begin
- ReleaseMemory(MultID); { release the memory }
- Table := GetTable(MultId);
- Index := 1;
- While Table^[Index].Number <> 0 Do { restore the interrupt vectors }
- Begin
- SetIntVec(Table^[Index].Number,Table^[Index].OldInt);
- Inc(Index);
- End;
- End;
-
- End.