UNIT Extend;

{$I platform.inc}

{ Ramon van der Winkel, 10 maart 1993 }

{ Deze routine breidt het aantal handles uit van maximaal 20 naar 250. }
{ Hiervoor wordt een stukje heap van 250 bytes aangevraagd. Dit wordt  }
{ echter nooit meer vrij gegeven.                                      }

{ History:

28-03-93  Aanpasssing gemaakt zodat de Extended Handles ook weer uitgezet
          kunnen worden. Dit is van belang bij het shellen naar dos
          bijvoorbeeld. Al het heap geheugen wordt dan weer vrij gemaakt en
          de handles tabel werkt dan niet meer. Dit kan QEMM errors
          veroorzaken.
}

INTERFACE

PROCEDURE UnExtendHandles;
PROCEDURE ExtendHandles;


IMPLEMENTATION

USES {$IFDEF PLATFORM_DOS_NOT_DPMI}
     Logs,
     {$ENDIF}
{$IFDEF PLATFORM_OS2}
     OS2Base;
{$ELSE}
     Dos;
{$ENDIF}

CONST MaxHandles = 100;

{$IFDEF PLATFORM_DOS_NOT_DPMI}
{$DEFINE DirectWay}
{$ENDIF}

VAR IsExtended : BOOLEAN;

{$IFDEF DirectWay}
TYPE HandlesArrayPtr = ^HandlesArray;
     HandlesArray    = ARRAY[1..MaxHandles] OF BYTE;

VAR HandlesPtr      : HandlesArrayPtr;
    OldHandlesPtr   : HandlesArrayPtr;
    OldHandlesCount : BYTE;
{$ENDIF (DirectWay) }


{--------------------------------------------------------------------------}
{ UnExtendHandles                                                          }
{                                                                          }
{ Deze routine zet de uitgebreidde handles weer terug. Alle files moeten   }
{ op dit moment gesloten zijn, behalve de eerste 20, want die worden terug }
{ gezet naar het oude array (waar er 20 in passen).                        }
{                                                                          }
PROCEDURE UnExtendHandles;

VAR Lp : BYTE;

BEGIN
{$IFDEF DirectWay}
     FOR Lp:=1 TO OldHandlesCount DO
         OldHandlesPtr^[Lp]:=HandlesPtr^[Lp];

     Mem[PrefixSeg:$32]:=OldHandlesCount;
     MemL[PrefixSeg:$34]:=Longint (OldHandlesPtr);

     {$IFDEF LogGetMem} LogGetMem (HandlesPtr,SizeOf (HandlesArray),'FreeMem Handles array'); {$ENDIF}
     FreeMem (HandlesPtr,SizeOf (HandlesArray));

{$ENDIF (DirectWay) }
{else: don't bother}
     IsExtended:=FALSE;
END;


{--------------------------------------------------------------------------}
{ ExtendHandles                                                            }
{                                                                          }
{ Deze routine zorgt dat er meer handles gebruikt kunnen worden. Bij       }
{ aanroep van deze procedure mogen er geen files open zijn, behalve dan de }
{ standaard 3 die altijd open zijn.                                        }
{                                                                          }

{ four different implementations, based on DOS, DPMI, WIN32 or OS2 target }

{$IFDEF PLATFORM_DPMI}
PROCEDURE ExtendHandles;

VAR Regs : Registers;

BEGIN
     IF IsExtended THEN
        Exit;

     { doesn't work for normal DOS because doesn't have enough }
     { free memory. Works for DPMI though.                     }
     { only works for DOS version 3.30 or higher.              }
     IF (Lo (DosVersion) >= 3) OR (Hi (DosVersion) >= 30) THEN
     BEGIN
          Regs.AH:=$67; { set handles count }
          Regs.BX:=99;  { deze moet oneven zijn ivm sommige buggy dos 3.30 }
          MsDos (Regs);
          {
          IF (Regs.Flags AND fCarry) > 0 THEN
          BEGIN
               WriteLn ('Extend error: ',Regs.AX);
               WriteLn ('8 = Insufficient memory');
          END;
          }
     END;

     IsExtended:=TRUE;
END;
{$ENDIF}

{$IFDEF PLATFORM_OS2}
PROCEDURE ExtendHandles;
BEGIN
     IF IsExtended THEN
        Exit;

     DosSetMaxFH (MaxHandles);

     IsExtended:=TRUE;
END;
{$ENDIF}

{$IFDEF PLATFORM_WIN32}
PROCEDURE ExtendHandles;
BEGIN
     IF IsExtended THEN
        Exit;

     {## to be added}

     IsExtended:=TRUE;
END;
{$ENDIF}

{$IFDEF DirectWay}
PROCEDURE ExtendHandles;

VAR Lp   : BYTE;

BEGIN
     IF IsExtended THEN
        Exit; { anders kunnen OldHandlesXXX verminkt worden! }

     { if you try this with the DPMI version it will GPF on you because }
     { the control memory is protected against tricks like these ;}
     GetMem (HandlesPtr,SizeOf (HandlesArray));
     {$IFDEF LogGetMem} LogGetMem (HandlesPtr,SizeOf (HandlesArray),'GetMem Handles array'); {$ENDIF}

     OldHandlesPtr:=Pointer (MemL[PrefixSeg:$34]);
     OldHandlesCount:=Mem[PrefixSeg:$32];

     FOR Lp:=1 TO OldHandlesCount DO
         HandlesPtr^[Lp]:=OldHandlesPtr^[Lp];

     FOR Lp:=OldHandlesCount+1 TO MaxHandles DO
         HandlesPtr^[Lp]:=255; { nog niet gebruikt }

     Mem[PrefixSeg:$32]:=MaxHandles;
     MemL[PrefixSeg:$34]:=Longint (HandlesPtr);

     IsExtended:=TRUE;
END;
{$ENDIF (DirectWay)}


{ unit initialization }

BEGIN
     IsExtended:=FALSE;
     ExtendHandles;   { Enable the extra handles }
END.
