{MEG-Glaser is not responsible for problems which arise from misuse.}
(* THIS UNIT HAS NO INTERFACE PROCEDURES, IT DOES THE WORK AUTOMATICALLY AT STARTUP OF THE APPLICATION PROGRAM. THE TYPED CONSTANT ExtendedHandles CAN BE INTERROGATED BY THE REST OF THE PROGRAM TO GET INFO ABOUT THE ALLOWED HANDLES, BUT IT IS SENSELESS TO WRITE TO IT.
THE UNIT SHALL BE INVOKED IN THE MAIN PROGRAM'S USES INSTRUCTION AT A VERY EARLY PLACE, BEFORE ANY OTHER UNITS WHICH COULD USE THE HEAP, ESPECIALLY BEFORE AN OVERLAY MANAGER
Program MyProg;
Uses CRT,DOS,EXPFILES,.... ;
To make it work: In CONFIG.SYS
FILES=99
see below for WinNT
*)
Interface
Uses DOS; {for the GetEnv below}
Const ExtendedHandles : Word = 15; {do not modify here, see below}
Implementation
(* the main problem is that MSDOS usually
has given all memory to the application program,
so there is no more free memory
available for the file handles.
If the application program asked
DOS to give him the maximum possible memory for the
heap (which is usual, with $M(stk,
hpmin, hpmax)) then the program must definitively
return some memory to DOS. I
am not sure how BP7 in protected mode or Windows will
behalve in this context, but
this is written for plain DOS *)
Function ShrinkHeapEnd:Boolean; {make free DOS memory for
AH=67H - handles}
Var ErAX,ErBX : Word;
Begin
ErAX := 0; ErBX := 0;
ASM
MOV AX,HeapEnd.Word[0] {ofs}
OR AX,AX
JNZ @@0
MOV BX,HeapEnd.Word[2] {seg}
MOV DI,BX {save
old top -> DI}
SUB BX,64 {64para
= 1kB sorry, I do not know, how much is necessary,
but 1kB always was sufficient}
MOV HeapEnd.Word[2],BX {adjust
the SYSTEM's heap first}
MOV AX,PrefixSeg {tell
DOS who we are}
MOV ES,AX
SUB BX,AX
{and how much mem we need now}
PUSH DS
PUSH BP
MOV AX,$4A00
INT $21 {give
back mem to DOS mem-handler}
POP BP
POP DS
JNC @@0
MOV ErBX,BX
@@0:
MOV ErAX,AX
END;
if ErAX = 0 then
ShrinkHeapEnd := true
else
Begin
Writeln('HeapShrinkError: ',ErAX,'
',ErBX); ReadLn;
ShrinkHeapEnd := false;
End;
End;
Procedure SetHandles(Handles : Word);
Var Rslt : Word;
Begin
Rslt := 0;
ASM
PUSH DS
PUSH BP
MOV AX,$6700
MOV BX,Handles
INT $21
POP BP
POP DS
JNC @@1
MOV Rslt,AX
@@1:
END;
if Rslt = 0 then
ExtendedHandles := Handles-5 {file
handles}
else
Begin
Write(^M^J'Error extending handles
',Rslt);
ReadLn;
End;
End;
Var HandleEnv : Integer; {not a very
elegant piece of code?}
Function GetHandleEnv : Boolean;
Var S : String[15];
I : Integer;
Begin
GetHandleEnv := false;
HandleEnv := 20;
S := GetEnv('USEFILES'); {or
whatever you intend. can be a constant as well,
if you know it at compile time}
if S > '' then
Begin
Val(S,HandleEnv,I);
GetHandleEnv := (I=0) and (HandleEnv
> 20) and (HandleEnv <= 100);
End;
End;
Begin
if GetHandleEnv then
if ShrinkHeapEnd then
SetHandles(HandleEnv); {success
is in ExtendedHandles}
End.
Hallo Herr Glaser,
habe schon lange nichts mehr
von mir hören lassen. Ich war derjenige,
der vor einigen Monaten Probleme
mit verlorenen Clustern im Zusammenhang
mit dem Öffnen von mehr
als 15 Dateien hatte.
Seit wir nun Ihre im Internet
veröffentlichte Routine zur Bewältigung
des Problems für Dos benutzen,
konnten wir keine weiteren verlorenen
Cluster in Zusammenhang mit
dieser Routine bringen.
Die "Vergewaltiger" Methoden
des Programmierers unserer ersten Lösung
scheinen somit tatsächlich
die Ursache gewesen zu sein.
Ich möchte mich für Ihre Unterstützung somit nochmals bedanken
MfG
W. Straßer
Hallo Herr Glaser,
ich habe jetzt einen Weg gefunden. Es gibt unter dem
Verzeichnis
C:\WINNT\SYSTEM32 eine Datei namens config.nt. In
dieser kann der
Files-Wert für die DOS-Sessions gesetzt werden
(in guter alter
CONFIG.SYS-Manier, also z. B. FILES=30).
Per Default ist der Wert auf 20 gestellt.
Rudi Ziegaus
Hello Mr. Glaser,
now I found a way. In the
folder C:\WINNT\SYSTEM32 is a file
named config.nt.
Here the files-value for DOS-sessions can be
set (in good old CONFIG.SYS
manner, eg. FILES=30).
Per default the value is
set to 20.