home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vp21beta.zip / ARTLSRC.RAR / DOS.PAS < prev    next >
Pascal/Delphi Source File  |  2000-08-15  |  16KB  |  533 lines

  1. //█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  2. //█                                                       █
  3. //█      Virtual Pascal Runtime Library.  Version 2.1.    █
  4. //█      DOS interface unit for OS/2 & Win32              █
  5. //█      ─────────────────────────────────────────────────█
  6. //█      Copyright (C) 1995-2000 vpascal.com              █
  7. //█                                                       █
  8. //▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  9.  
  10. {$S-,R-,Q-,I-,H-,T-,X+}                     // Common compiler directive
  11. {&Cdecl-,OrgName-,AlignRec-,Delphi+,Use32+} // VP specific compiler directives
  12.  
  13. unit Dos;
  14.  
  15. interface
  16.  
  17. uses VpSysLow;
  18.  
  19. const
  20.  
  21. { Flags bit masks }
  22.  
  23.   fCarry     = $0001;
  24.   fParity    = $0004;
  25.   fAuxiliary = $0010;
  26.   fZero      = $0040;
  27.   fSign      = $0080;
  28.   fOverflow  = $0800;
  29.  
  30. { File mode magic numbers }
  31.  
  32.   fmClosed = $A55AD7B0;
  33.   fmInput  = $A55AD7B1;
  34.   fmOutput = $A55AD7B2;
  35.   fmInOut  = $A55AD7B3;
  36.  
  37. { File attribute constants }
  38.  
  39.   ReadOnly  = $01;
  40.   Hidden    = $02;
  41.   SysFile   = $04;
  42.   VolumeID  = $08;      // N/A under OS/2
  43.   Directory = $10;
  44.   Archive   = $20;
  45. {$IFDEF OS2}
  46.   AnyFile   = $37;
  47. {$ELSE}
  48.   AnyFile   = $3F;
  49. {$ENDIF}
  50.  
  51. type
  52.  
  53. { String types }
  54.  
  55.   ComStr  = String;     // Command line string
  56.   PathStr = String;     // File pathname string
  57.   DirStr  = String;     // Drive and directory string
  58.   NameStr = String;     // File name string
  59.   ExtStr  = String;     // File extension string
  60.  
  61. { Typed-file and untyped-file record }
  62.  
  63.   FileRec = record
  64.     Handle:   Longint;                  // File Handle
  65.     Mode:     Longint;                  // Current file mode
  66.     RecSize:  Longint;                  // I/O operation record size
  67.     Private:  array [1..28] of Byte;    // Reserved
  68.     UserData: array [1..32] of Byte;    // User data area
  69.     Name:     array [0..259] of Char;   // File name (ASCIIZ)
  70.   end;
  71.  
  72. { Textfile record }
  73.  
  74.   TextBuf = array [0..127] of Char;
  75.   TextRec = record
  76.     Handle:    Longint;                 // File Handle
  77.     Mode:      Longint;                 // Current file mode
  78.     BufSize:   Longint;                 // Text File buffer size
  79.     BufPos:    Longint;                 // Buffer current position
  80.     BufEnd:    Longint;                 // Buffer ending position
  81.     BufPtr:    ^TextBuf;                // Pointer to the buffer
  82.     OpenFunc:  Pointer;                 // Open Text File function @
  83.     InOutFunc: Pointer;                 // In/Out ...
  84.     FlushFunc: Pointer;                 // Flush ...
  85.     CloseFunc: Pointer;                 // Close ...
  86.     UserData:  array [1..32] of Byte;   // User data area
  87.     Name:      array [0..259] of Char;  // File name (ASCIIZ)
  88.     Buffer:    TextBuf;                 // Default I/O buffer
  89.   end;
  90.  
  91. { Search record used by FindFirst and FindNext }
  92.  
  93.   SearchRec = record
  94.     Handle: Longint;
  95.     Filler1: Longint;
  96.     Attr: Byte;
  97.     Time: Longint;
  98.     Size: Longint;
  99.     Name: ShortString;
  100.     Filler2: array[0..3] of Char;
  101. {$IFDEF WIN32}
  102.     Filler3: array[0..321] of Char;
  103. {$ENDIF}
  104. {$IFDEF DPMI32}
  105.     Private_data: array[1..sizeof(TOSSearchRec)-4-4-1-4-4-256-4] of Byte;
  106. {$ENDIF}
  107. {$IFDEF LINUX}
  108.     Pattern: ShortString;
  109.     FileMode: LongInt;
  110.     Directory: ShortString;
  111. {$ENDIF}
  112.   end;
  113.  
  114. { Date and time record used by PackTime and UnpackTime }
  115.  
  116.   DateTime = record
  117.     Year,Month,Day,Hour,Min,Sec: Word;
  118.   end;
  119.  
  120. { Error status variable }
  121.  
  122. threadvar
  123.   DosError: Integer;
  124.   ExecFlags: Longint;
  125.  
  126. { Exec flags }
  127.  
  128. const
  129.   efSync  = 0;          // exec_Sync
  130.   efAsync = 1;          // exec_AsyncResult
  131.  
  132. function DosVersion: Word;
  133. procedure GetDate(var Year,Month,Day,DayOfWeek: Word);
  134. procedure SetDate(Year,Month,Day: Word);
  135. procedure GetTime(var Hour,Minute,Second,Sec100: Word);
  136. procedure SetTime(Hour,Minute,Second,Sec100: Word);
  137. procedure GetVerify(var Verify: Boolean);
  138. procedure SetVerify(Verify: Boolean);
  139. function DiskFree(Drive: Byte): Longint;
  140. function DiskSize(Drive: Byte): Longint;
  141. procedure GetFAttr(var F; var Attr: Word);
  142. procedure SetFAttr(var F; Attr: Word);
  143. procedure GetFTime(var F; var Time: Longint);
  144. procedure SetFTime(var F; Time: Longint);
  145. procedure FindFirst(const Path: PathStr; Attr: Word; var F: SearchRec);
  146. procedure FindNext(var F: SearchRec);
  147. procedure UnpackTime(P: Longint; var T: DateTime);
  148. procedure PackTime(var T: DateTime; var P: Longint);
  149. function FSearch(const Path: PathStr; const DirList: String): PathStr;
  150. function FExpand(const Path: PathStr): PathStr;
  151. function EnvCount: Integer;
  152. function EnvStr(Index: Integer): String;
  153. function GetEnv(const EnvVar: String): String;
  154. procedure FSplit(const Path: PathStr; var Dir: DirStr; var Name: NameStr; var Ext: ExtStr);
  155. procedure Exec(const Path: PathStr; const ComLine: ComStr);
  156. function DosExitCode: Word;
  157.  
  158.  
  159. { The following procedures are not implemented
  160.  
  161. procedure Intr(IntNo: Byte; var Regs: Registers);
  162. procedure MsDos(var Regs: Registers);
  163. procedure GetCBreak(var Break: Boolean);
  164. procedure SetCBreak(Break: Boolean);
  165. procedure GetIntVec(IntNo: Byte; var Vector: Pointer);
  166. procedure SetIntVec(IntNo: Byte; Vector: Pointer);
  167. procedure Keep(ExitCode: Word);
  168.  
  169. }
  170.  
  171. { SwapVectors remains for compatibility but do nothing }
  172.  
  173. procedure SwapVectors;
  174.  
  175. { The following support have been added }
  176.  
  177. procedure FindClose(var F: SearchRec);
  178.  
  179. implementation
  180.  
  181. uses Strings;
  182.  
  183. type
  184.   TDateTimeRec = record
  185.     FTime,FDate: SmallWord;
  186.   end;
  187.  
  188. // Assigns the value of the last error code to DosError and returns it.
  189.  
  190. function SetDosError(ErrCode: Integer): Integer;
  191. begin
  192.   DosError := ErrCode;
  193.   Result := ErrCode;
  194. end;
  195.  
  196. // Returns the version number of the operating system. The low byte of the
  197. // result is the major version number, and the high byte is the minor version
  198. // number. For example, OS/2 2.10 returns $0A14, i.e. 20 in the low byte, and
  199. // 10 in the high byte.
  200.  
  201. function DosVersion: Word;
  202. begin
  203.   Result := SysOsVersion;
  204. end;
  205.  
  206. // Returns the current date set in the operating system. Ranges of the
  207. // values returned are: Year 1980-2099, Month 1-12, Day 1-31 and
  208. // DayOfWeek 0-6 (0 corresponds to Sunday).
  209.  
  210. procedure GetDate(var Year,Month,Day,DayOfWeek: Word);
  211. begin
  212.   SysGetDateTime(@Year, @Month, @Day, @DayOfWeek, nil, nil, nil, nil);
  213. end;
  214.  
  215. // Sets the current date set in the operating system. Valid parameter
  216. // ranges are: Year 1980-2099, Month 1-12 and Day 1-31. If the date is
  217. // not valid, the function call is ignored.
  218.  
  219. procedure SetDate(Year,Month,Day: Word);
  220. begin
  221.   SysSetDateTime(@Year, @Month, @Day, nil, nil, nil, nil);
  222. end;
  223.  
  224. // Returns the current time set in the operating system. Ranges of the
  225. // values returned are: Hour 0-23, Minute 0-59, Second 0-59 and Sec100
  226. // (hundredths of seconds) 0-99.
  227.  
  228. procedure GetTime(var Hour,Minute,Second,Sec100: Word);
  229. begin
  230.   SysGetDateTime(nil, nil, nil, nil, @Hour, @Minute, @Second, @Sec100);
  231.   Sec100 := Sec100 div 10;
  232. end;
  233.  
  234. // Sets the time in the operating system. Valid parameter ranges are:
  235. // Hour 0-23, Minute 0-59, Second 0-59 and Sec100 (hundredths of seconds
  236. // 0-99. If the time is not valid, the function call is ignored.
  237.  
  238. procedure SetTime(Hour,Minute,Second,Sec100: Word);
  239. begin
  240.   Sec100 := Sec100 * 10;
  241.   SysSetDateTime(nil, nil, nil, @Hour, @Minute, @Second, @Sec100);
  242. end;
  243.  
  244. // GetVerify returns the state of the verify flag in OS/2. When off
  245. // (False), disk writes are not verified. When on (True), all disk
  246. // writes are verified to insure proper writing.
  247.  
  248. procedure GetVerify(var Verify: Boolean);
  249. begin
  250.   Verify := SysVerify(False, False);
  251. end;
  252.  
  253. // SetVerify sets the state of the verify flag in OS/2.
  254.  
  255. procedure SetVerify(Verify: Boolean);
  256. begin
  257.   SysVerify(True, Verify);
  258. end;
  259.  
  260. // Returns the number of free bytes on the specified drive number
  261. // (0=Default,1=A,2=B,..). Returns -1 if the drive number is invalid.
  262.  
  263. function DiskFree(Drive: Byte): Longint;
  264. begin
  265.   Result := SysDiskFree(Drive);
  266. end;
  267.  
  268. // Returns the size in bytes of the specified drive number (0=Default,
  269. // 1=A,2=B,..). Returns -1 if the drive number is invalid.
  270.  
  271. function DiskSize(Drive: Byte): Longint;
  272. begin
  273.   Result := SysDiskSize(Drive);
  274. end;
  275.  
  276. // Returns the attributes of a file. F must be a file variable (typed,
  277. // untyped or textfile) which has been assigned a name. The attributes
  278. // are examined by ANDing with the attribute masks defined as constants
  279. // above. Errors are reported in DosError.
  280.  
  281. procedure GetFAttr(var F; var Attr: Word);
  282. begin
  283.   SetDosError(SysGetFileAttr(FileRec(F).Name, Attr));
  284. end;
  285.  
  286. // Sets the attributes of a file. F must be a file variable (typed,
  287. // untyped or textfile) which has been assigned a name. The attribute
  288. // alue is formed by adding (or ORing) the appropriate attribute masks
  289. // efined as constants above. Errors are reported in DosError.
  290.  
  291. procedure SetFAttr(var F; Attr: Word);
  292. begin
  293.   SetDosError(SysSetFileAttr(FileRec(F).Name, Attr));
  294. end;
  295.  
  296. // Returns the date and time a file was last written. F must be a file
  297. // variable (typed, untyped or textfile) which has been assigned and
  298. // opened. The Time parameter may be unpacked throgh a call to
  299. // UnpackTime. Errors are reported in DosError.
  300.  
  301. procedure GetFTime(var F; var Time: Longint);
  302. begin
  303.   SetDosError(SysGetFileTime(FileRec(F).Handle, Time));
  304. end;
  305.  
  306. // Sets the date and time a file was last written. F must be a file
  307. // variable (typed, untyped or textfile) which has been assigned and
  308. // opened. The Time parameter may be created through a call to PackTime.
  309. // Errors are reported in DosError.
  310.  
  311. procedure SetFTime(var F; Time: Longint);
  312. begin
  313.   SetDosError(SysSetFileTime(FileRec(F).Handle, Time));
  314. end;
  315.  
  316. // Converts a 4-byte packed date/time returned by FindFirst, FindNext or
  317. // GetFTime into a DateTime record.
  318.  
  319. procedure UnpackTime(P: Longint; var T: DateTime);
  320. var
  321.   FDateTime: TDateTimeRec absolute P;
  322. begin
  323.   with T,FDateTime do
  324.   begin
  325.     Year  := (FDate and $FE00) shr 9 + 1980;
  326.     Month := (FDate and $01E0) shr 5;
  327.     Day   := (FDate and $001F);
  328.     Hour  := (FTime and $F800) shr 11;
  329.     Min   := (FTime and $07E0) shr 5;
  330.     Sec   := (FTime and $001F) * 2;
  331.   end;
  332. end;
  333.  
  334. // Converts a DateTime record into a 4-byte packed date/time used by
  335. // SetFTime.
  336.  
  337. procedure PackTime(var T: DateTime; var P: Longint);
  338. var
  339.   FDateTime: TDateTimeRec absolute P;
  340. begin
  341.   with T,FDateTime do
  342.   begin
  343.     FDate := (Year - 1980) shl 9 + Month shl 5 + Day;
  344.     FTime := Hour shl 11 + Min shl 5 + (Sec div 2);
  345.   end;
  346. end;
  347.  
  348. // Splits the file name specified by Path into its three components. Dir
  349. // is set to the drive and directory path with any leading and trailing
  350. // backslashes, Name is set to the file name, and Ext is set to the
  351. // extension with a preceding dot. Each of the component strings may
  352. // possibly be empty, if Path contains no such component.
  353.  
  354. procedure FSplit(const Path: PathStr; var Dir: DirStr; var Name: NameStr; var Ext: ExtStr);
  355. var
  356.   I,NamePos,ExtPos: Integer;
  357. begin
  358.   NamePos := 0;
  359.   ExtPos  := 256;
  360.   for I := 1 to Length(Path) do
  361.   case Path[I] of
  362.     ':', {$IFDEF LINUX} '/' {$ELSE} '\' {$ENDIF} :
  363.       begin
  364.         NamePos := I;
  365.         ExtPos  := 256;
  366.       end;
  367.     '.': ExtPos := I;
  368.   end;
  369.   Dir  := Copy(Path, 1, NamePos);
  370.   Name := Copy(Path, NamePos+1, ExtPos-NamePos-1);
  371.   Ext  := Copy(Path, ExtPos, 255);
  372. end;
  373.  
  374. // EnvCount returns the number of strings contained in the OS environment.
  375.  
  376. function EnvCount: Integer;
  377. var
  378.   P: PChar;
  379.   Count: Integer;
  380. begin
  381.   P := SysGetEnvironment;
  382.   Count := 0;
  383.   while P^ <> #0 do
  384.   begin
  385.     repeat Inc(P) until (P-1)^ = #0;
  386.     Inc(Count);
  387.   end;
  388.   Result := Count;
  389. end;
  390.  
  391. // Returns a specified environment string. The returned string is of the
  392. // form "VAR=VALUE". The index of the first string is one. If Index is
  393. // less than one or greater than EnvCount,EnvStr returns an empty string.
  394.  
  395. function EnvStr(Index: Integer): String;
  396. var
  397.   P: PChar;
  398.   Count: Integer;
  399. begin
  400.   Result := '';
  401.   if Index > 0 then
  402.   begin
  403.     P := SysGetEnvironment;
  404.     Count := 1;
  405.     while (Count < Index) and (P^ <> #0) do
  406.     begin
  407.       repeat Inc(P) until (P-1)^ = #0;
  408.       Inc(Count);
  409.     end;
  410.     Result := StrPas(P);
  411.   end;
  412. end;
  413.  
  414. // Returns the value of a specified environment variable. The variable
  415. // name can be in upper or lower case, but it must not include the '='
  416. // character. If the specified environment variable does not exist,
  417. // GetEnv returns an empty string.
  418.  
  419. function GetEnv(const EnvVar: String): String;
  420. var
  421.   P: PChar;
  422.   L: Word;
  423.   EnvVarBuf: array [0..255] of Char;
  424. begin
  425.   StrPCopy(EnvVarBuf, EnvVar);
  426.   L := Length(EnvVar);
  427.   P := SysGetEnvironment;
  428.   while P^ <> #0 do
  429.   begin
  430.     if (StrLIComp(P, EnvVarBuf, L) = 0) and (P[L] = '=') then
  431.     begin
  432.       Result := StrPas(P + L + 1);
  433.       Exit;
  434.     end;
  435.     Inc(P, StrLen(P) + 1);
  436.   end;
  437.   Result := '';
  438. end;
  439.  
  440. // Remains for backward compatibility with TP & BP only
  441.  
  442. procedure SwapVectors;
  443. begin
  444. end;
  445.  
  446. // Searches the specified (or current) directory for the first entry
  447. // that matches the specified filename and attributes. The result is
  448. // returned in the specified search record. Errors (and no files found)
  449. // are reported in DosError.
  450.  
  451. procedure FindFirst(const Path: PathStr; Attr: Word; var F: SearchRec);
  452. var
  453.   PathBuf: array [0..SizeOf(PathStr)-1] of Char;
  454. begin
  455.   SetDosError(SysFindFirst(StrPCopy(PathBuf, Path), Attr, TOSSearchRec(F), False));
  456. end;
  457.  
  458. // Returns the next entry that matches the name and attributes specified
  459. // in a previous call to FindFirst. The search record must be one passed
  460. // to FindFirst. Errors (and no more files) are reported in DosError.
  461.  
  462. procedure FindNext(var F: SearchRec);
  463. begin
  464.   SetDosError(SysFindNext(TOSSearchRec(F), False));
  465. end;
  466.  
  467. // Ends the search, closes the search record. FindClose should be issued
  468. // whenever search record is no longer needed. Errors are reported in DosError.
  469.  
  470. procedure FindClose(var F: SearchRec);
  471. begin
  472.   SetDosError(SysFindClose(TOSSearchRec(F)));
  473. end;
  474.  
  475. // Searches for the file given by Path in the list of directories given
  476. // by DirList. The directory paths in DirList must be separated by
  477. // semicolons. The search always starts with the current directory of
  478. // the current drive. The returned value is a fully qualified file name
  479. // or an empty string if the file could not be located.
  480.  
  481. function FSearch(const Path: PathStr; const DirList: String): PathStr;
  482. var
  483.   PathBuf:    array[0..259] of Char;
  484.   DirListBuf: array[0..259] of Char;
  485.   ResBuf:     array[0..259] of Char;
  486. begin
  487.   Result := StrPas(SysFileSearch(ResBuf, StrPCopy(PathBuf, Path), StrPCopy(DirListBuf, DirList)));
  488. end;
  489.  
  490. // FExpand expands the file name in Path into a fully qualified file
  491. // name. The resulting name consists of a drive letter, a colon, a root
  492. // relative directory path, and a file name. Embedded '.' and '..'
  493. // directory references are removed.
  494.  
  495. function FExpand(const Path: PathStr): PathStr;
  496. var
  497.   I: Integer;
  498.   PathBuf: array[0..259] of Char;
  499.   ResBuf:  array[0..259] of Char;
  500. begin
  501.   Result := StrPas(SysFileExpand(ResBuf, StrPCopy(PathBuf, Path)));
  502. {$IFDEF UpperCase}
  503.   for I := 1 to Length(Result) do
  504.     Result[I] := UpCase(Result[I]);
  505. {$ENDIF}
  506. end;
  507.  
  508. // Executes another program. The program is specified by the Path
  509. // parameter, and the command line is specified by the CmdLine parameter.
  510. // ExecFlags specifies Exec type (synchronous or asynchronous). To
  511. // execute an OS/2 internal command, run CMD.EXE, e.g.
  512. // "Exec(GetEnv('COMSPEC'),'/C DIR *.PAS');". Note the /C in front of
  513. // the command. Errors are reported in DosError.
  514.  
  515. procedure Exec(const Path: PathStr; const ComLine: ComStr);
  516. var
  517.   PathBuf:    array [0..255] of Char;
  518.   CmdLineBuf: array [0..255] of Char;
  519. begin
  520.   SetDosError(SysExecute(StrPCopy(PathBuf, Path), StrPCopy(CmdLineBuf, ComLine), nil, ExecFlags = efAsync, nil, -1, -1, -1));
  521. end;
  522.  
  523. // DosExitCode returns the exit code of a sub-process. To obtain the
  524. // correct exit code make sure that ExecFlags variable has not been
  525. // changed between calls to Exec and DosExitCode.
  526.  
  527. function DosExitCode: Word;
  528. begin
  529.   Result := SysExitCode;
  530. end;
  531.  
  532. end.
  533.