home *** CD-ROM | disk | FTP | other *** search
/ Freelog 22 / freelog 22.iso / Prog / Djgpp / GPC2952B.ZIP / lib / gcc-lib / djgpp / 2.952 / units / dos.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-02-08  |  22.0 KB  |  780 lines

  1. {
  2. Portable BP compatible Dos unit
  3.  
  4. This unit supports most of the routines and declarations of BP's Dos
  5. unit.
  6.  
  7. NOTES:
  8.  
  9. - The procedures Keep, GetIntVec, SetIntVec are not supported since
  10.   they make only sense for Dos real-mode programs (and GPC compiled
  11.   programs do not run in real-mode, even on x86 under Dos). The
  12.   procedures Intr and MsDos are only supported under DJGPP if
  13.   `__BP_UNPORTABLE_ROUTINES__' is defined (with the
  14.   `-D__BP_UNPORTABLE_ROUTINES__' option). A few other routines are
  15.   also only supported with this define, but on all platforms (but
  16.   they are crude hacks, that's why they are not supported without
  17.   this define).
  18.  
  19. - The internal structure of file variables (FileRec and TextRec) is
  20.   different in GPC. However, as far as TFDDs are concerned, there
  21.   are other ways to achieve the same in GPC, see the GPC unit.
  22.  
  23. Copyright (C) 1998-2001 Free Software Foundation, Inc.
  24.  
  25. Authors: Frank Heckenbach <frank@pascal.gnu.de>
  26.          Prof. Abimbola A. Olowofoyeku <African_Chief@bigfoot.com>
  27.  
  28. This file is part of GNU Pascal.
  29.  
  30. GNU Pascal is free software; you can redistribute it and/or modify
  31. it under the terms of the GNU General Public License as published by
  32. the Free Software Foundation; either version 2, or (at your option)
  33. any later version.
  34.  
  35. GNU Pascal is distributed in the hope that it will be useful,
  36. but WITHOUT ANY WARRANTY; without even the implied warranty of
  37. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  38. GNU General Public License for more details.
  39.  
  40. You should have received a copy of the GNU General Public License
  41. along with GNU Pascal; see the file COPYING. If not, write to the
  42. Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  43. 02111-1307, USA.
  44.  
  45. As a special exception, if you link this file with files compiled
  46. with a GNU compiler to produce an executable, this does not cause
  47. the resulting executable to be covered by the GNU General Public
  48. License. This exception does not however invalidate any other
  49. reasons why the executable file might be covered by the GNU General
  50. Public License.
  51. }
  52.  
  53. {$gnu-pascal,B-,I-}
  54. {$if __GPC_RELEASE__ < 20000412}
  55. {$error This unit requires GPC release 20000412 or newer.}
  56. {$endif}
  57.  
  58. unit Dos;
  59.  
  60. interface
  61.  
  62. uses GPC, System;
  63.  
  64. type
  65.   Byte8 = Cardinal (8);
  66.   TDosAttr = Word;
  67.   GPC_AnyFile = AnyFile; { in order to have AnyFile parameters,
  68.                            while AnyFile is redefined below }
  69.  
  70. const
  71.   { File attribute constants }
  72.   ReadOnly      = $01;
  73.   Hidden        = $02; { set for dot files except '.' and '..' }
  74.   SysFile       = $04; { not supported }
  75.   VolumeID      = $08; { not supported }
  76.   Directory     = $10;
  77.   Archive       = $20; { means: not executable }
  78.   {$local W-} AnyFile = $3f; {$endlocal}
  79.  
  80.   { Flag bit masks -- only used by the unportable Dos routines }
  81.   FCarry     = 1;
  82.   FParity    = 4;
  83.   FAuxiliary = $10;
  84.   FZero      = $40;
  85.   FSign      = $80;
  86.   FOverflow  = $800;
  87.  
  88.   { DosError codes }
  89.   DosError_FileNotFound = 2;
  90.   DosError_PathNotFound = 3;
  91.   DosError_AccessDenied = 5;
  92.   DosError_InvalidMem   = 9;
  93.   DosErorr_InvalidEnv   = 10;
  94.   DosError_NoMoreFiles  = 18;
  95.   DosError_IOError      = 29;
  96.   DosError_ReadFault    = 30;
  97.  
  98. type
  99.   { String types. Not used in this unit, but declared for
  100.     compatibility. }
  101.   ComStr  = String [127];        { Command line string }
  102.   PathStr = String [79];         { File pathname string }
  103.   DirStr  = String [67];         { Drive and directory string }
  104.   NameStr = String [8];          { File name string }
  105.   ExtStr  = String [4];          { File extension string }
  106.  
  107.   TextBuf = array [0 .. 127] of Char;
  108.  
  109.   { Search record used by FindFirst and FindNext }
  110.   SearchRecFill = packed array [1 .. 21] of Byte8;
  111.   SearchRec = {$ifdef __BP_TYPE_SIZES__} packed {$endif} record
  112.     Fill : SearchRecFill;
  113.     Attr : Byte8;
  114.     Time, Size : LongInt;
  115.     Name : {$ifdef __BP_TYPE_SIZES__}
  116.            String [12]
  117.            {$else}
  118.            TString
  119.            {$endif}
  120.   end;
  121.  
  122.   { Date and time record used by PackTime and UnpackTime }
  123.   DateTime = record
  124.     Year, Month, Day, Hour, Min, Sec : Word
  125.   end;
  126.  
  127.   { 8086 CPU registers -- only used by the unportable Dos routines }
  128.   Registers = record
  129.   case Boolean of
  130.     False : (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Word16);
  131.     True  : (AL, AH, BL, BH, CL, CH, DL, DH : Byte8)
  132.   end;
  133.  
  134. var
  135.   { Error status variable }
  136.   DosError : Integer = 0;
  137.  
  138. procedure GetDate (var Year, Month, Day, DayOfWeek : Word);                     asmname '_p_getdate';
  139. procedure GetTime (var Hour, Minute, Second, Sec100 : Word);                    asmname '_p_gettime';
  140. procedure GetCBreak (var BreakOn : Boolean);                                    asmname '_p_getcbreak';
  141. procedure SetCBreak (BreakOn : Boolean);                                        asmname '_p_setcbreak';
  142. { GetVerify and SetVerify are dummies except for DJGPP (in the
  143.   assumption that any real OS knows by itself when and how to verify
  144.   its disks). }
  145. procedure GetVerify (var VerifyOn : Boolean);                                   asmname '_p_getverify';
  146. procedure SetVerify (VerifyOn : Boolean);                                       asmname '_p_setverify';
  147. function  DiskFree (Drive : Byte) : LongInt;                                    asmname '_p_diskfree';
  148. function  DiskSize (Drive : Byte) : LongInt;                                    asmname '_p_disksize';
  149. procedure GetFAttr (var F : GPC_AnyFile; var Attr : TDosAttr);                  asmname '_p_getfattr';
  150. procedure SetFAttr (var F : GPC_AnyFile; Attr : TDosAttr);                      asmname '_p_setfattr';
  151. procedure GetFTime (var F : GPC_AnyFile; var aTime : LongInt);                  asmname '_p_getftime';
  152. procedure SetFTime (var F : GPC_AnyFile; aTime : LongInt);                      asmname '_p_setftime';
  153.  
  154. { FindFirst and FindNext are quite inefficient since they emulate
  155.   all the brain-dead Dos stuff. If at all possible, the standard
  156.   routines OpenDir, ReadDir and CloseDir (in the GPC unit) should be
  157.   used instead. }
  158. procedure FindFirst (const Path : String; Attr : TDosAttr; var SR : SearchRec); asmname '_p_findfirst';
  159. procedure FindNext  (var SR : SearchRec);                                       asmname '_p_findnext';
  160.  
  161. procedure FindClose (var SR : SearchRec);                                       asmname '_p_findclose';
  162. procedure UnpackTime (P : LongInt; var T : DateTime);                           asmname '_p_unpacktime';
  163. procedure PackTime (const T : DateTime; var P : LongInt);                       asmname '_p_packtime';
  164. function  FSearch (const aFileName, DirList : String) : TString;                asmname '_p_fsearch';
  165. function  FExpand (const Path : String) : TString;                              asmname '_p_fexpand';
  166. procedure FSplit  (const Path : String; var Dir, Name, Ext : String);           asmname '_p_fsplit';
  167. function  EnvCount : Integer;
  168. function  EnvStr (EnvIndex : Integer) : TString;
  169. function  GetEnv (const EnvVar : String) : TString;                             asmname '_p_getenv';
  170. procedure SwapVectors;
  171. { Exec executes a process via Execute, so RestoreTerminal is called with
  172.   the argument True before and False after executing the process. }
  173. procedure Exec (const Path, Params : String);
  174. function  DosExitCode : Word;
  175.  
  176. { Unportable Dos-only routines and declarations }
  177.  
  178. {$ifdef __BP_UNPORTABLE_ROUTINES__}
  179. {$ifdef DJGPP}
  180. { These are unportable Dos-only declarations and routines, since
  181.   interrupts are Dos and CPU specific (and have no place in a
  182.   high-level program, anyway). }
  183. procedure Intr (IntNo : Byte; var Regs : Registers);                            asmname '_p_intr';
  184. procedure MsDos (var Regs : Registers);                                         asmname '_p_msdos';
  185. {$endif}
  186.  
  187. { Though probably all non-Dos system have versions numbers as well,
  188.   returning them here would usually not do what is expected, e.g.
  189.   testing if certain Dos features are present by comparing the
  190.   version number. Therefore, this routine always returns 7 (i.e.,
  191.   version 7.0) on non-Dos systems, in the assumption that any real
  192.   OS has at least the features of Dos 7. }
  193. function  DosVersion : Word;                                                    asmname '_p_dosversion';
  194.  
  195. { Changing the system date and time is a system administration task,
  196.   not allowed to a normal process. On non-Dos systems, these
  197.   routines emulate the changed date/time, but only for GetTime and
  198.   GetDate (not the RTS date/time routines), and only for this
  199.   process, not for child processes or even the parent process or
  200.   system-wide. }
  201. procedure SetDate (Year, Month, Day : Word);                                    asmname '_p_setdate';
  202. procedure SetTime (Hour, Minute, Second, Sec100 : Word);                        asmname '_p_settime';
  203. {$endif}
  204.  
  205. implementation
  206.  
  207. type
  208.   PLongInt = ^LongInt;
  209.  
  210. const
  211.   MSPerDay = 86400000000;
  212.  
  213. var
  214.   DosExitCodeVar : Word = 0;
  215.   TimeDelta : MicroSecondTimeType = 0;
  216.  
  217. procedure GetDate (var Year, Month, Day, DayOfWeek : Word);
  218. var
  219.   t : MicroSecondTimeType;
  220.   ts : TimeStamp;
  221. begin
  222.   t := GetMicroSecondTime + TimeDelta;
  223.   UnixTimeToTimeStamp (t div 1000000, ts);
  224.   Year      := ts.Year;
  225.   Month     := ts.Month;
  226.   Day       := ts.Day;
  227.   DayOfWeek := ts.DayOfWeek
  228. end;
  229.  
  230. procedure GetTime (var Hour, Minute, Second, Sec100 : Word);
  231. var
  232.   t : MicroSecondTimeType;
  233.   ts : TimeStamp;
  234. begin
  235.   t := GetMicroSecondTime + TimeDelta;
  236.   UnixTimeToTimeStamp (t div 1000000, ts);
  237.   Hour   := ts.Hour;
  238.   Minute := ts.Minute;
  239.   Second := ts.Second;
  240.   Sec100 := (t mod 1000000) div 10000
  241. end;
  242.  
  243. function DiskFree (Drive : Byte) : LongInt;
  244. var
  245.   Path : String (2);
  246.   Buf : StatFSBuffer;
  247. begin
  248.   if Drive = 0 then
  249.     Path := DirSelf
  250.   else
  251.     Path := Succ ('a', Drive - 1) + ':';
  252.   StatFS (Path, Buf);
  253.   if IOResult = 0 then
  254.     DiskFree := Buf.BlockSize * Buf.BlocksFree
  255.   else
  256.     begin
  257.       DosError := DosError_AccessDenied;
  258.       DiskFree := - 1
  259.     end
  260. end;
  261.  
  262. function DiskSize (Drive : Byte) : LongInt;
  263. var
  264.   Path : String (2);
  265.   Buf : StatFSBuffer;
  266. begin
  267.   if Drive = 0 then
  268.     Path := DirSelf
  269.   else
  270.     Path := Succ ('a', Drive - 1) + ':';
  271.   StatFS (Path, Buf);
  272.   if IOResult = 0 then
  273.     DiskSize := Buf.BlockSize * Buf.BlocksTotal
  274.   else
  275.     begin
  276.       DosError := DosError_AccessDenied;
  277.       DiskSize := - 1
  278.     end
  279. end;
  280.  
  281. procedure GetFAttr (var F : GPC_AnyFile; var Attr : TDosAttr);
  282. var
  283.   b : BindingType;
  284.   s : TString;
  285.   d : OrigInt;
  286. begin
  287.   b := Binding (F);
  288.   Attr := 0;
  289.   if not (b.Bound and (b.Existing or b.Directory or b.Special)) then
  290.     DosError := DosError_FileNotFound
  291.   else
  292.     begin
  293.       DosError := 0;
  294.       if b.Directory      then Attr := Attr or Directory;
  295.       if not b.Writable   then Attr := Attr or ReadOnly;
  296.       if not b.Executable then Attr := Attr or Archive;
  297.       d := Length (b.Name);
  298.       while (d > 0) and not (b.Name [d] in DirSeparators) do Dec (d);
  299.       if (Length (b.Name) > d + 1) and (b.Name [d + 1] =  '.') and
  300.         ((Length (b.Name) > d + 2) or  (b.Name [d + 2] <> '.')) then
  301.         Attr := Attr or Hidden
  302.     end
  303. end;
  304.  
  305. procedure SetFAttr (var F : GPC_AnyFile; Attr : TDosAttr);
  306. var b : BindingType;
  307. begin
  308.   b := Binding (F);
  309.   if not b.Bound then
  310.     begin
  311.       DosError := DosError_FileNotFound;
  312.       Exit
  313.     end;
  314.   if Attr and ReadOnly = 0
  315.     then or  (b.Mode, fm_UserWritable) { Set only user write permissions, for reasons of safety! }
  316.     else and (b.Mode, not (fm_UserWritable or fm_GroupWritable or fm_OthersWritable));
  317.   if Attr and Archive = 0
  318.     then or  (b.Mode, fm_UserExecutable or fm_GroupExecutable or fm_OthersExecutable)
  319.     else and (b.Mode, not (fm_UserExecutable or fm_GroupExecutable or fm_OthersExecutable));
  320.   ChMod (F, b.Mode);
  321.   if IOResult <> 0 then DosError := DosError_AccessDenied
  322. end;
  323.  
  324. procedure GetFTime (var F : GPC_AnyFile; var aTime : LongInt);
  325. var
  326.   b : BindingType;
  327.   Year, Month, Day, Hour, Minute, Second : OrigInt;
  328.   dt : DateTime;
  329. begin
  330.   b := Binding (F);
  331.   if not (b.Bound and (b.Existing or b.Directory or b.Special)) then
  332.     DosError := DosError_FileNotFound
  333.   else
  334.     begin
  335.       if b.ModificationTime >= 0 then
  336.         begin
  337.           UnixTimeToTime (b.ModificationTime, Year, Month, Day, Hour, Minute, Second);
  338.           dt.Year  := Year;
  339.           dt.Month := Month;
  340.           dt.Day   := Day;
  341.           dt.Hour  := Hour;
  342.           dt.Min   := Minute;
  343.           dt.Sec   := Second;
  344.           PackTime (dt, aTime)
  345.         end
  346.       else
  347.         aTime := 0;
  348.       DosError := 0
  349.     end
  350. end;
  351.  
  352. procedure SetFTime (var F : GPC_AnyFile; aTime : LongInt);
  353. var
  354.   dt : DateTime;
  355.   ut: UnixTimeType;
  356. begin
  357.   UnpackTime (aTime, dt);
  358.   with dt do ut := TimeToUnixTime (Year, Month, Day, Hour, Min, Sec);
  359.   DosError := DosError_AccessDenied;
  360.   if ut >= 0 then
  361.     begin
  362.       SetFileTime (F, ut, ut);
  363.       if IOResult = 0 then DosError := 0
  364.     end
  365. end;
  366.  
  367. { Since there's no explicit closing of FindFirst/FindNext, FindList keeps
  368.   tracks of all running searches so they can be closed automatically when
  369.   necessary, and Magic indicates if a SearchRec is currently in use. }
  370.  
  371. const
  372.   srOpened = $2424d00f;
  373.   srDone   = $4242f00d;
  374.  
  375. type
  376.   TSRFillInternal = packed record
  377.     Magic  : OrigInt;
  378.     Unused : packed array [1..SizeOf (SearchRecFill) - SizeOf (OrigInt)] of Byte
  379.   end;
  380.  
  381.   PPFindList = ^PFindList;
  382.   PFindList  = ^TFindList;
  383.   TFindList  = record
  384.     Next : PFindList;
  385.     SR   : ^SearchRec;
  386.     Dir,
  387.     Name,
  388.     Ext  : TString;
  389.     Attr : TDosAttr;
  390.     PDir : Pointer;
  391.   end;
  392.  
  393. var
  394.   FindList : PFindList = nil;
  395.  
  396. procedure CloseFind (PTemp : PPFindList);
  397. var Temp : PFindList;
  398. begin
  399.   Temp := PTemp^;
  400.   CloseDir (Temp^.PDir);
  401.   TSRFillInternal (Temp^.SR^.Fill).Magic := srDone;
  402.   PTemp^ := Temp^.Next;
  403.   Dispose (Temp)
  404. end;
  405.  
  406. procedure FindFirst (const Path : String; Attr : TDosAttr; var SR : SearchRec);
  407. var
  408.   Temp : PFindList;
  409.   PTemp : PPFindList;
  410. begin
  411.   { If SR was used before, close it first }
  412.   PTemp := @FindList;
  413.   while (PTemp^ <> nil) and (PTemp^^.SR <> @SR) do PTemp := @PTemp^^.Next;
  414.   if PTemp^ <> nil then
  415.     begin
  416.       CloseFind (PTemp);
  417.       if IOResult <> 0 then DosError := DosError_ReadFault
  418.     end;
  419.   if Attr and not (ReadOnly or Archive) = VolumeID then
  420.     begin
  421.       DosError := DosError_NoMoreFiles;
  422.       Exit
  423.     end;
  424.   New (Temp);
  425.   FSplit (Path, Temp^.Dir, Temp^.Name, Temp^.Ext);
  426.   if Temp^.Dir = '' then Temp^.Dir := DirSelf + DirSeparator;
  427.   if Temp^.Ext = '' then Temp^.Ext := ExtSeparator;
  428.   Temp^.SR := @SR;
  429.   Temp^.Attr := Attr;
  430.   Temp^.PDir := OpenDir (Temp^.Dir);
  431.   if IOResult <> 0 then
  432.     begin
  433.       TSRFillInternal (SR.Fill).Magic := srDone;
  434.       Dispose (Temp);
  435.       DosError := DosError_NoMoreFiles;
  436.       Exit
  437.     end;
  438.   TSRFillInternal (SR.Fill).Magic := srOpened;
  439.   Temp^.Next := FindList;
  440.   FindList := Temp;
  441.   FindNext (SR)
  442. end;
  443.  
  444. procedure FindNext (var SR : SearchRec);
  445. var
  446.   Temp : PFindList;
  447.   PTemp : PPFindList;
  448.   Name, Dir, Nam, Ext : TString;
  449.   F : Text;
  450.   TmpAttr : TDosAttr;
  451.   TmpTime : LongInt;
  452.  
  453.   { Emulate Dos brain-damaged file name wildcard matching }
  454.   function MatchPart (const aName, Mask : String) : Boolean;
  455.   var i : OrigInt;
  456.   begin
  457.     for i := 1 to Length (Mask) do
  458.       case Mask [i] of
  459.         '?' : ;
  460.         '*' : return True;
  461.         else
  462.           if (i > Length (aName)) or (FileNameLoCase (aName [i]) <> FileNameLoCase (Mask [i])) then return False
  463.       end;
  464.     MatchPart := Length (Mask) >= Length (aName)
  465.   end;
  466.  
  467. begin
  468.   DosError := 0;
  469.   { Check if SR is still valid }
  470.   case TSRFillInternal (SR.Fill).Magic of
  471.     srOpened : ;
  472.     srDone   : begin
  473.                  DosError := DosError_NoMoreFiles;
  474.                  Exit
  475.                end;
  476.     else
  477.       DosError := DosError_InvalidMem;
  478.       Exit
  479.   end;
  480.   PTemp := @FindList;
  481.   while (PTemp^ <> nil) and (PTemp^^.SR <> @SR) do PTemp := @PTemp^^.Next;
  482.   Temp := PTemp^;
  483.   if Temp = nil then
  484.     begin
  485.       DosError := DosError_InvalidMem;
  486.       Exit
  487.     end;
  488.   repeat
  489.     Name := ReadDir (Temp^.PDir);
  490.     if Name = '' then
  491.       begin
  492.         CloseFind (PTemp);
  493.         if IOResult = 0
  494.           then DosError := DosError_NoMoreFiles
  495.           else DosError := DosError_ReadFault;
  496.         Exit
  497.       end;
  498.     Assign (F, Temp^.Dir + Name);
  499.     GetFAttr (F, TmpAttr);
  500.     SR.Attr := TmpAttr;
  501.     FSplit (Name, Dir, Nam, Ext);
  502.     if Ext = '' then Ext := ExtSeparator
  503.   until MatchPart (Nam, Temp^.Name) and MatchPart (Ext, Temp^.Ext) and
  504.         { Emulate Dos brain-damaged file attribute matching }
  505.         ((Temp^.Attr and (Hidden or SysFile) <> 0) or (TmpAttr and Hidden    = 0)) and
  506.         ((Temp^.Attr and Directory           <> 0) or (TmpAttr and Directory = 0));
  507.   SR.Name := Name;
  508.   if DosError <> 0 then Exit;
  509.   GetFTime (F, TmpTime);
  510.   SR.Time := TmpTime;
  511.   if Binding (F).Existing then
  512.     begin
  513.       Reset (F);
  514.       SR.Size := FileSize (F);
  515.       Close (F)
  516.     end
  517.   else
  518.     SR.Size := 0
  519. end;
  520.  
  521. procedure FindClose (var SR : SearchRec);
  522. var PTemp : PPFindList;
  523. begin
  524.   PTemp := @FindList;
  525.   while (PTemp^ <> nil) and (PTemp^^.SR <> @SR) do PTemp := @PTemp^^.Next;
  526.   if PTemp^ <> nil then
  527.     begin
  528.       CloseFind (PTemp);
  529.       if IOResult <> 0 then DosError := DosError_ReadFault
  530.     end
  531. end;
  532.  
  533. procedure UnpackTime (P : LongInt; var T : DateTime);
  534. begin
  535.   T.Year  := (P shr 25) and $7f + 1980;
  536.   T.Month := (P shr 21) and $f;
  537.   T.Day   := (P shr 16) and $1f;
  538.   T.Hour  := (P shr 11) and $1f;
  539.   T.Min   := (P shr 5) and $3f;
  540.   T.Sec   := 2 * (P and $1f)
  541. end;
  542.  
  543. procedure PackTime (const T : DateTime; var P : LongInt);
  544. begin
  545.   P := (LongInt (T.Year) - 1980) shl 25 + LongInt (T.Month) shl 21 + LongInt (T.Day) shl 16
  546.        + T.Hour shl 11 + T.Min shl 5 + T.Sec div 2
  547. end;
  548.  
  549. function EnvCount : Integer;
  550. begin
  551.   EnvCount := Environment^.Count
  552. end;
  553.  
  554. function EnvStr (EnvIndex : Integer) : TString;
  555. begin
  556.   if (EnvIndex < 1) or (EnvIndex > EnvCount)
  557.     then EnvStr := ''
  558.     else EnvStr := CString2String (Environment^.CStrings [EnvIndex])
  559. end;
  560.  
  561. procedure SwapVectors;
  562. begin
  563.   { Nothing to be done }
  564. end;
  565.  
  566. procedure Exec (const Path, Params : String);
  567. begin
  568.   DosExitCodeVar := Execute (Path + ' ' + Params);
  569.   if IOResult <> 0 then DosError := DosError_FileNotFound
  570. end;
  571.  
  572. function DosExitCode : Word;
  573. begin
  574.   DosExitCode := DosExitCodeVar
  575. end;
  576.  
  577. {$ifdef DJGPP}
  578.  
  579. type
  580.   TDPMIRegs = record
  581.     EDI, ESI, EBP, Reserved, EBX, EDX, ECX, EAX : Word32;
  582.     Flags, ES, DS, FS, GS, IP, CS, SP, SS : Word16
  583.   end;
  584.  
  585. procedure RealModeInterrupt (InterruptNumber : Integer; var Regs : TDPMIRegs); asmname '__dpmi_int';
  586.  
  587. procedure Intr (IntNo : Byte; var Regs : Registers);
  588. var DPMIRegs : TDPMIRegs;
  589. begin
  590.   FillChar (DPMIRegs, SizeOf (DPMIRegs), 0);
  591.   with DPMIRegs do
  592.     begin
  593.       EDI := Regs.DI;
  594.       ESI := Regs.SI;
  595.       EBP := Regs.BP;
  596.       EBX := Regs.BX;
  597.       EDX := Regs.DX;
  598.       ECX := Regs.CX;
  599.       EAX := Regs.AX;
  600.       Flags := Regs.Flags;
  601.       ES := Regs.ES;
  602.       DS := Regs.DS;
  603.       RealModeInterrupt (IntNo, DPMIRegs);
  604.       Regs.DI := EDI;
  605.       Regs.SI := ESI;
  606.       Regs.BP := EBP;
  607.       Regs.BX := EBX;
  608.       Regs.DX := EDX;
  609.       Regs.CX := ECX;
  610.       Regs.AX := EAX;
  611.       Regs.Flags := Flags;
  612.       Regs.ES := ES;
  613.       Regs.DS := DS
  614.     end
  615. end;
  616.  
  617. procedure MsDos (var Regs : Registers);
  618. begin
  619.   Intr ($21, Regs)
  620. end;
  621.  
  622. function DosVersion : Word;
  623. var Regs : Registers;
  624. begin
  625.   Regs.AX := $3000;
  626.   MsDos (Regs);
  627.   DosVersion := Regs.AX
  628. end;
  629.  
  630. procedure SetDate (Year, Month, Day : Word);
  631. var Regs : Registers;
  632. begin
  633.    Regs.AX := $2b00;
  634.    Regs.CX := Year;
  635.    Regs.DX := $100 * Month + Day;
  636.    MsDos (Regs)
  637. end;
  638.  
  639. procedure SetTime (Hour, Minute, Second, Sec100 : Word);
  640. var Regs : Registers;
  641. begin
  642.   Regs.AX := $2d00;
  643.   Regs.CX := $100 * Hour + Minute;
  644.   Regs.DX := $100 * Second + Sec100;
  645.   MsDos (Regs)
  646. end;
  647.  
  648. procedure GetCBreak (var BreakOn : Boolean);
  649. var Regs : Registers;
  650. begin
  651.   Regs.AX := $3300;
  652.   MsDos (Regs);
  653.   BreakOn := Regs.DL <> 0
  654. end;
  655.  
  656. procedure SetCBreak (BreakOn : Boolean);
  657. var Regs : Registers;
  658. begin
  659.   Regs.AX := $3301;
  660.   Regs.DX := Ord (BreakOn);
  661.   MsDos (Regs)
  662. end;
  663.  
  664. procedure GetVerify (var VerifyOn : Boolean);
  665. var Regs : Registers;
  666. begin
  667.   Regs.AX := $5400;
  668.   MsDos (Regs);
  669.   VerifyOn := Regs.AL <> 0
  670. end;
  671.  
  672. procedure SetVerify (VerifyOn : Boolean);
  673. var Regs : Registers;
  674. begin
  675.   Regs.AX := $2e00 + Ord (VerifyOn);
  676.   MsDos (Regs)
  677. end;
  678.  
  679. {$else}
  680.  
  681. {$ifdef _WIN32}
  682.  
  683. {$define WINAPI(X) asmname X; attribute (stdcall)}
  684.  
  685. const
  686.   StdInputHandle = - 10;
  687.   EnableProcessedInput = 1;
  688.  
  689. function GetConsoleMode (ConsoleHandle : Integer; var Mode : Integer) : Boolean; WINAPI ('GetConsoleMode');
  690. function SetConsoleMode (ConsoleHandle : Integer; Mode : Integer) : Boolean; WINAPI ('SetConsoleMode');
  691. function GetStdHandle (StdHandle : Integer) : Integer; WINAPI ('GetStdHandle');
  692.  
  693. procedure GetCBreak (var BreakOn : Boolean);
  694. var Mode : Integer;
  695. begin
  696.   if GetConsoleMode (GetStdHandle (StdInputHandle), Mode) then
  697.     BreakOn := Mode and EnableProcessedInput <> 0
  698.   else
  699.     BreakOn := True
  700. end;
  701.  
  702. procedure SetCBreak (BreakOn : Boolean);
  703. var
  704.   i : Integer;
  705.   Dummy : Boolean;
  706. begin
  707.   if GetConsoleMode (GetStdHandle (StdInputHandle), i) then
  708.     begin
  709.       if BreakOn
  710.         then i := i or EnableProcessedInput
  711.         else i := i and not EnableProcessedInput;
  712.       Dummy := SetConsoleMode (GetStdHandle (StdInputHandle), i)
  713.     end
  714. end;
  715.  
  716. {$else}
  717.  
  718. procedure GetCBreak (var BreakOn : Boolean);
  719. begin
  720.   BreakOn := GetInputSignals
  721. end;
  722.  
  723. procedure SetCBreak (BreakOn : Boolean);
  724. begin
  725.   SetInputSignals (BreakOn)
  726. end;
  727.  
  728. {$endif}
  729.  
  730. var
  731.   LastVerify : Boolean = True;
  732.  
  733. procedure GetVerify (var VerifyOn : Boolean);
  734. begin
  735.   VerifyOn := LastVerify
  736. end;
  737.  
  738. procedure SetVerify (VerifyOn : Boolean);
  739. begin
  740.   LastVerify := VerifyOn
  741. end;
  742.  
  743. function DosVersion : Word;
  744. begin
  745.   DosVersion := 7
  746. end;
  747.  
  748. { We cannot easily set the date without the time or vice versa while
  749.   treating DST correctly under all circumstances. }
  750. procedure SetDateTime (Year, Month, Day, Hour, Minute, Second, Sec100 : Word);
  751. begin
  752.   TimeDelta := MicroSecondTimeType (TimeToUnixTime (Year, Month, Day, Hour, Minute, Second)) * 1000000 + Sec100 * 10000 - GetMicroSecondTime
  753. end;
  754.  
  755. procedure SetDate (Year, Month, Day : Word);
  756. var Hour, Minute, Second, Sec100 : Word;
  757. begin
  758.   GetTime (Hour, Minute, Second, Sec100);
  759.   SetDateTime (Year, Month, Day, Hour, Minute, Second, Sec100)
  760. end;
  761.  
  762. procedure SetTime (Hour, Minute, Second, Sec100 : Word);
  763. var Year, Month, Day, DayOfWeek : Word;
  764. begin
  765.   GetDate (Year, Month, Day, DayOfWeek);
  766.   SetDateTime (Year, Month, Day, Hour, Minute, Second, Sec100)
  767. end;
  768.  
  769. {$endif}
  770.  
  771. to end do
  772.   while FindList <> nil do
  773.     begin
  774.       var i : OrigInt = IOResult;
  775.       CloseFind (@FindList);
  776.       InOutRes := i
  777.     end;
  778.  
  779. end.
  780.