[Back to DOS SWAG index] [Back to Main SWAG index] [Original]

    {$R-,S-}

    {PEXTEND
     ------------------------------------------------------------------
     This unit provides a single function, DpmiExtendHandles, for
     extending the file handle table for DOS protected mode applications
     under Borland Pascal 7.0.

     The standard DOS call for this purpose (AH = $67) does odd things to
     DOS memory when run from a BP7 pmode program. If you Exec from a
     program that has extended the handle table, DOS memory will be
     fragmented, leaving a stranded block of almost 64K at the top of DOS
     memory. The function implemented here avoids this problem.

     If you haven't used an ExtendHandles function before, note that you
     cannot get more handles than the FILES= statement in CONFIG.SYS
     allows. (Other utilities such as FILES.COM provided with QEMM do the
     same thing.) However, even if you have FILES=255, any single program
     cannot open more than 20 files (and DOS uses up 5 of those) unless
     you use a routine like DpmiExtendHandles. This routine allows up to
     255 open files as long as the FILES= statement provides for them.

     This code works only for DOS 3.0 or later. Since (to my knowledge)
     DPMI cannot be used with earlier versions of DOS, the code doesn't
     check the DOS version.

     Don't call this function more than once in the same program.

     Version 1.0,
       Written 12/15/92, Kim Kokkonen, TurboPower Software
    }

    {$IFNDEF DPMI}
      !! Error: this unit for DPMI applications only
    {$ENDIF}

    unit PExtend;
      {-Extend handle table for DOS protected mode applications}

    interface

    function DpmiExtendHandles(Handles : Byte) : Word;
      {-Extend handle table to Handles size.
        Returns 0 for success, else a DOS error code.
        Does nothing and returns 0 if Handles <= 20.}

    implementation

    uses
      WinApi;

    function DpmiExtendHandles(Handles : Byte) : Word;
    type
      DosMemRec =
        record
          Sele, Segm : Word;
        end;
    var
      OldTable : Pointer;
      OldSize : Word;
      NewTable : Pointer;
      DosMem : DosMemRec;
    begin
      DpmiExtendHandles := 0;
      if Handles <= 20 then
        Exit;

      {Allocate new table area in DOS memory}
      LongInt(DosMem) := GlobalDosAlloc(Handles);
      if LongInt(DosMem) = 0 then begin
        DpmiExtendHandles := 8;
        Exit;
      end;

      {Initialize new table with closed handles}
      NewTable := Ptr(DosMem.Sele, 0);
      FillChar(NewTable^, Handles, $FF);

      {Copy old table to new. Assume old table in PrefixSeg}
      OldTable := Ptr(PrefixSeg, MemW[PrefixSeg:$34]);
      OldSize := Mem[PrefixSeg:$32];
      move(OldTable^, NewTable^, OldSize);

      {Set new handle table size and pointer}
      Mem[PrefixSeg:$32] := Handles;
      MemW[PrefixSeg:$34] := 0;
      MemW[PrefixSeg:$36] := DosMem.Segm;
    end;

    end.

[Back to DOS SWAG index] [Back to Main SWAG index] [Original]