home *** CD-ROM | disk | FTP | other *** search
- ISRES - Routines to determine if a program is already resident
- --------------------------------------------------------------
- Brian Foley
- TurboPower Software
- 1/90
- Version 1.0
- Released to the public domain
-
- Overview
- ----------------------------------------------------------------------------
-
- The main purpose of ISRES is to provide a facility for non-resident programs
- similar to TPTSR/OPTSR's standard module interface. That is, it provides
- routines that allow a program to determine if it is being loaded for a
- second time. The typical use for ISRES is in a program that allows other
- programs to be executed, and needs to prevent the user from loading a second
- copy of the same program. The supplied example program, RESTEST, illustrates
- the use of ISRES in such a case.
-
- A secondary use of ISRES is to provide a communication channel between
- programs. When you call ISRES's Install routine, you can specify a pointer
- to a data structure or routine that might be of interest to other programs.
- This hook can be used to allow other programs access to a program's data, by
- passing Install the address of that data. Or it can be used to allow other
- programs to call a special routine, by passing Install the address of that
- routine.
-
- When using the hook for the latter purpose, keep in mind that the routine in
- question must either 1) be compiled FAR or 2) be of type interrupt. If the
- routine is *not* of type interrupt, it cannot refer to any data stored in
- the data segment unless it sets up the DS register first. Practically
- speaking, this means that the routine must be written in assembly language.
- If the procedure *is* of type interrupt, the DS register will be set up
- automatically, so the routine may refer to global data.
-
- If you plan to use this hook to store the address of a procedure of type
- interrupt, we suggest that you read about the standard module interface in
- OPTSR (see Object Professional manual) or TPTSR (see Turbo Professional
- manual). The technique you would need to employ, described there, basically
- involves using ISRES's IsLoaded routine to retrieve the address of the
- procedure, and OPINT/TPINT's EmulateInt to call it.
-
- ISRES and TPTSR/OPTSR/OPSWAP
- ----------------------------------------------------------------------------
-
- The technique used by ISRES to track down other programs is essentially
- identical to that used by OPTSR, OPSWAP (also part of Object Professional),
- and TPTSR. Consequently, you can use ISRES to locate a TSR that has called
- InstallModule and, conversely, a TSR can use either ModuleInstalled or
- ModulePtrByName to locate a non-resident program that uses ISRES. For
- example, a program using ISRES could locate SMACS by executing the statement
-
- SmacsIsLoaded := IsLoaded('SUPER MACS', P);
-
- If SMACS is found, P will contain the address of SMAC'ss command entry
- routine. Similarly, if a non-resident program using ISRES had executed the
- statement
-
- InstallModule('MYPROG', @MyData);
-
- then a TSR could obtain the address of MyData by executing
-
- const
- MyProgName : string[6] = 'MYPROG';
- var
- MyProgIfc : IfcPtr;
- MyDataPtr : Pointer;
- begin
- ...
- MyProgIfc := ModulePtrByName(MyProgName);
- if MyProgIfc = nil then
- {MYPROG not found}
- else
- MyDataPtr := MyProgIfc^.CmdEntryPtr;
- ...
- end.
-
- The important distinction to keep in mind here is that the pointer returned
- by IsLoaded (if IsLoaded is True) is identical to the address passed to
- Install (ISRES) or InstallModule (TPTSR/OPTSR/OPSWAP1). The pointer returned
- by ModulePtrByName is the address of an IfcRecord (a record structure
- defined by TPTSR/OPTSR/OPSWAP1). To obtain the address of a TSR's command
- entry routine or a non-resident program's UserHook, you must look at the
- CmdEntryPtr field in the IfcRecord.
-
- ISRES and OPEXEC/EXECSWAP
- ----------------------------------------------------------------------------
-
- ISRES is designed to allow it to be used in conjunction with the OPEXEC unit
- in Object Professional, as well as the earlier EXECSWAP unit available on
- CompuServe and elsewhere. That is, all of its data is stored in its code
- segment, not in the data segment or on the heap. To use the two units (ISRES
- and OPEXEC/EXECSWAP) together successfully, however, you must be certain
- that ISRES appears *after* the other unit in the main program's USES list.
- This insures that all of ISRES's code will remain resident in memory after
- the bulk of the program has been swapped to disk or EMS.
-
- Interfaced Declarations and Routines
- ----------------------------------------------------------------------------
-
- ISRES interfaces the following types and routines:
-
- type
- ProgramName = string[8];
-
- Name of a program to be installed. Note the limit of 8 characters.
-
- procedure Install(Name : ProgramName; UserHook : Pointer);
-
- Adds the specified program to a linked list of installed programs.
- UserHook, if not nil, should point to a procedure or data structure of
- potential interest to other programs. Does nothing if Name is empty.
-
- function IsLoaded(Name : String; var UserHook : Pointer) : Boolean;
-
- This routine searches the linked list of installed programs looking for
- Name. If the program is found, IsLoaded will return True, and UserHook
- will contain the pointer that was passed to Install when the program went
- resident. The search is case-sensitive: 'MyProg' is not the same as
- 'MYPROG'. Note that Name may be longer than 8 characters: this allows
- IsLoaded to locate TSRs written with TPTSR, OPTSR, or OPSWAP.
-
- procedure Uninstall;
-
- Removes the current program, if already installed, from the linked list of
- installed programs.
-
- procedure Init16;
-
- Install ISRES's INT $16 handler. This routine is called automatically when
- the program begins, and normally does not need to be called thereafter. It
- should be called only if Restore16 has previously been called.
-
- procedure Restore16;
-
- Restore the INT $16 vector grabbed by Init16. This routine is called
- automatically when the program ends, and normally does not need to be
- called directly. It is interfaced only to allow the INT $16 vector to be
- given back temporarily. It can be regrabbed by calling Init16.