home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / utility / extend / extend.pas < prev   
Pascal/Delphi Source File  |  1987-10-26  |  5KB  |  127 lines

  1. {$R-,S-,I-,D-,T-,F-,V-,B-,N-}
  2.  
  3. unit Extend;
  4.  
  5. { This unit allows a program to open more than the standard DOS maximum of 20
  6.   open files at one time.  You must also be sure to set a FILES=XX statement
  7.   in your CONFIG.SYS file.  This program installs a special interrupt handler
  8.   under DOS 2.x and uses some semi-documented features under DOS 3.x.  This
  9.   unit USES the DOS unit and should be used before any other units other than
  10.   the DOS unit.  This code was based upon earlier work by Randy Forgaard, Bela
  11.   Lubkin and Kim Kokkonen.  See EXTEND.DOC for more information.
  12.  
  13.   Scott Bussinger
  14.   Professional Practice Systems
  15.   110 South 131st Street
  16.   Tacoma, WA  98444
  17.   (206)531-8944
  18.   Compuserve [72247,2671]
  19.  
  20.   Version 3.0 -- 10/16/1987 -- Reworked as a UNIT for use with Turbo Pascal 4
  21.                                EXTEND.ASM reworked to be compatible with A86 assembler
  22.                                Added support for DOS 3.3
  23.           2.5 --  3/16/1987 -- EXTEND.ASM worked on by Kim Kokkonen and Brian Foley to work
  24.                                  with Turbo Extender and whittle off a few clock cycles
  25.           2.4 -- 12/16/1986 -- Fixed a problem with DUP under DOS 2.x
  26.                                Now allocates the new handle table on heap
  27.                                  under DOS 3.x (compatible with TDebug+)
  28.           2.3 -- 11/18/1986 -- EXTEND now only affects DOS calls made from
  29.                                  same code segment it was installed from (fixes
  30.                                  problems with EXEC and batch files and already
  31.                                  resident TSR programs
  32.           2.2 -- 10/04/1986 -- Fixed problem with EXEC function destroying all
  33.                                  registers including the stack
  34.                                Changed way that original handle number is kept
  35.                                Permit FORCEDUP to change a standard handle
  36.                                Improve some comments
  37.           2.1 -- 10/02/1986 -- Fixed problem of Turbo assuming the registers
  38.                                  valid after the DOS call
  39.           2.0 -- 10/01/1986 -- Initial release of interrupt handler version
  40.           1.5                  Last version of EXTEND.PAS using explicit
  41.                                  calls to extend files. }
  42.  
  43. interface
  44.  
  45. uses Dos;
  46.  
  47. implementation
  48.  
  49. type HandleArray = array[0..254] of byte;
  50.      HandleArrayPtr = ^HandleArray;
  51.  
  52. var ExitSave: pointer;                 { Previous exit procedure }
  53.     HandlePtrPtr: ^HandleArrayPtr;     { Pointer to pointer to current table }
  54.     NewHandleTable: HandleArrayPtr;    { Pointer to new table }
  55.     OldInt21: pointer;                 { Save old INT 21 }
  56.     OldHandleTable: HandleArrayPtr;    { Pointer to original table }
  57.     OldNumHandles: byte;               { Original number of handles }
  58.  
  59.  
  60. {$L EXTEND }
  61. procedure ExtendInit; external;        { Initialize interrupt handler }
  62. procedure ExtendHandler; external;     { Replacement INT 21 handler }
  63.  
  64.  
  65. procedure ExtendHandles;
  66.   { Install the extended handles interrupt.  No files (other than
  67.     standard handles should be open when unit starts up. }
  68.   var Reg: Registers;
  69.   begin
  70.   Reg.AH := $30;
  71.   msdos(Reg);                          { Get DOS version number }
  72.   if Reg.AL = 2
  73.    then
  74.     begin
  75.     GetIntVec($21,OldInt21);           { Install interrupt handler under DOS 2.x }
  76.     SetIntVec($21,@ExtendHandler);
  77.     ExtendInit                         { Initialize the interrupt handler }
  78.     end
  79.    else
  80.     begin                              { Change location of handle table }
  81.     { Allocate space for new handle table on heap }
  82.     new(NewHandleTable);
  83.     { Fill new table with unused entries }
  84.     fillchar(NewHandleTable^,sizeof(HandleArray),$FF);
  85.  
  86.     OldNumHandles := mem[prefixseg:$0032];        { Get old table length }
  87.     mem[prefixseg:$0032] := sizeof(HandleArray);  { Set new table length }
  88.  
  89.     HandlePtrPtr := ptr(prefixseg,$0034); { Pointer to pointer to handles }
  90.     { Remember the old handle table location }
  91.     OldHandleTable := HandlePtrPtr^;
  92.     { Copy the current handle table to the new handle table }
  93.     move(OldHandleTable^,NewHandleTable^,OldNumHandles);
  94.     { Point to new handle table on heap }
  95.     HandlePtrPtr^ := NewHandleTable
  96.     end
  97.   end;
  98.  
  99. {$F+}
  100. procedure UnExtendHandles;
  101.   { Uninstall the extended handles interrupt.  All files (other
  102.     than standard handles) should be closed before unit exits. }
  103.   var Reg: Registers;
  104.   begin
  105.   Reg.AH := $30;
  106.   msdos(Reg);                          { Get DOS version number }
  107.   if Reg.AL = 2
  108.    then
  109.     SetIntVec($21,OldInt21)            { Restore old INT21 handler }
  110.    else
  111.     begin                              { Restore original handle table }
  112.     mem[prefixseg:$0032] := OldNumHandles; { Restore old table length }
  113.     HandlePtrPtr^ := OldHandleTable;   { Restore original handle table }
  114.     { Now copy the current handle table back }
  115.     move(NewHandleTable^,OldHandleTable^,OldNumHandles);
  116.     dispose(NewHandleTable)            { Release the heap space }
  117.     end;
  118.   ExitProc := ExitSave                 { Chain to next exit routine }
  119.   end;
  120. {$F-}
  121.  
  122. begin
  123. ExitSave := ExitProc;                  { Remember the previous exit routine }
  124. ExitProc := @UnExtendHandles;          { Install our exit routine }
  125. ExtendHandles                          { Install the extended handles }
  126. end.
  127.