home *** CD-ROM | disk | FTP | other *** search
- {$I-,O-,R-}
-
- unit Extend;
-
- { This unit allows a program to open more than the standard DOS maximum of 20
- open files at one time. You must also be sure to set a FILES=XX statement
- in your CONFIG.SYS file. This program installs a special interrupt handler
- under DOS 2.x, some semi-documented features under DOS 3.x prior to
- DOS 3.3 and the DOS extend files call under DOS 3.3 or later. This
- unit USES the DOS unit and should be used before any other units other than
- the DOS unit. This code was based upon earlier work by Randy Forgaard, Bela
- Lubkin and Kim Kokkonen. See EXTEND.DOC for more information.
-
- Scott Bussinger
- Professional Practice Systems
- 110 South 131st Street
- Tacoma, WA 98444
- (206)531-8944
- Compuserve [72247,2671] }
-
- { ** Revision History **
- 1 EXTEND.PAS 9-Mar-89,`SCOTT' First version using TLIB -- Based on 3.2
- 2 EXTEND.PAS 15-Sep-89,`SCOTT'
- Added SwapVectorsExtend procedure
- Put handle table into DOS memory
- Use DOS 3.3 extended handles function when available
- 3 EXTEND.PAS 2-Oct-89,`SCOTT'
- Fixed bug in determining the DOS version
- 4 EXTEND.PAS 5-Oct-89,`SCOTT'
- Yet another bug in the DosVersion detection
- 5 EXTEND.PAS 19-Nov-90,`SCOTT'
- New version of EXTEND that is compatible with Turbo Pascal 6.0
- Modified the documentation and version numbers to be less confusing
- ** Revision History ** }
-
- interface
-
- procedure SwapVectorsExtend;
- { Swap interrupt vectors taken over by Extend unit with system vectors }
-
- implementation
-
- uses Dos,Shrink;
-
- type HandleArray = array[0..254] of byte; { Room for 255 handles }
- HandleArrayPtr = ^HandleArray;
-
- var DosMemory: pointer; { Pointer to memory gained from DOS }
- ExitSave: pointer; { Previous exit procedure }
- OldInt21: pointer; { Save old INT 21 }
- OldHandleTable: HandleArrayPtr; { Pointer to original table }
- OldNumHandles: byte; { Original number of handles }
-
- {$L EXTEND }
- procedure ExtendInit; external; { Initialize interrupt handler }
- procedure ExtendHandler; external; { Replacement INT 21 handler }
-
- procedure SwapVectorsExtend;
- { Swap interrupt vectors taken over by Extend unit with system vectors }
- var TempVector: pointer;
- begin
- if lo(DosVersion) = 2 then
- begin
- GetIntVec($21,TempVector); { Swap the INT 21 vectors }
- SetIntVec($21,OldInt21);
- OldInt21 := TempVector
- end
- end;
-
- procedure ExtendHandles;
- { Install the extended handles interrupt. No files (other than
- standard handles) should be open when unit starts up. }
- var Regs: Registers;
- begin
- if lo(DosVersion) = 2
- then
- begin
- GetIntVec($21,OldInt21); { Install interrupt handler under DOS 2.x }
- ExtendInit; { Initialize the interrupt handler }
- SetIntVec($21,@ExtendHandler)
- end
- else
- begin
- DosNewShrink(DosMemory,sizeof(HandleArray));
- if DosMemory <> nil then { There wasn't enough memory for a handle table, so just quit }
- if (lo(DosVersion)>=4) or (hi(DosVersion)>=30) { Does this DOS version support the handles call? }
- then
- begin
- DosDispose(DosMemory); { Free up the DOS memory block so that the next function will succeed }
- with Regs do
- begin
- AH := $67; { Tell DOS to allow us 255 handles }
- BX := 255; { KEEP THIS NUMBER ODD TO AVOID BUG IN SOME VERSIONS OF DOS 3.3!! }
- MsDos(Regs)
- end
- end
- else
- begin
- fillchar(DosMemory^,sizeof(HandleArray),$FF); { Initialize new handles as unused }
- OldNumHandles := mem[prefixseg:$0032]; { Get old table length }
- OldHandleTable := pointer(ptr(prefixseg,$0034)^); { Save address of old table }
- mem[prefixseg:$0032] := sizeof(HandleArray); { Set new table length }
- pointer(meml[prefixseg:$0034]) := DosMemory; { Point to new handle table }
- move(OldHandleTable^,DosMemory^,OldNumHandles) { Copy the current handle table to the new handle table }
- end
- end
- end;
-
- {$F+}
- procedure ExitHandler;
- {$F-}
- { Uninstall the extended handles interrupt. All files (other
- than standard handles) should be closed before unit exits. }
- begin
- ExitProc := ExitSave; { Chain to next exit routine }
- SwapVectorsExtend { Restore original interrupt vectors }
- end;
-
- begin
- ExitSave := ExitProc; { Remember the previous exit routine }
- ExitProc := @ExitHandler; { Install our exit routine }
- ExtendHandles { Enable the extra handles }
- end.