home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
turbopas
/
tppop16.arc
/
UNHOOK.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-09-28
|
4KB
|
149 lines
{$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.