home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MSDOS.ZIP / MSDOS.PAS
Encoding:
Pascal/Delphi Source File  |  1987-08-08  |  14.5 KB  |  487 lines

  1. {***********************************************************************
  2.  
  3.          MS-DOS COMMANDS NOT SUPPORTED DIRECTLY BY TURBO PASCAL
  4.                          Version 1.00, 10/11/85
  5.  
  6.   Procedure
  7.      or        Subroutine
  8.   Function        Name                       Description
  9.   --------- ---------------- -------------------------------------------
  10.  
  11.   Function  GetAttribute     Return the value of a specified file's
  12.                              attribute byte.
  13.  
  14.   Procedure SetAttribute     Set a specified file's attribute byte.
  15.  
  16.   Function  GetBreak         Return a boolean value reporting the
  17.                              current state of the DOS break switch:
  18.                              on=true, off=false.
  19.  
  20.   Procedure SetBreak         Turn DOS break switch on/off based on a
  21.                              boolean parameter: on=true, off=false.
  22.  
  23.   Function  GetDTA           Return a pointer to current disk transfer
  24.                              area.
  25.  
  26.   Procedure SetDTA           Set the current disk transfer area to the
  27.                              address specified in a pointer variable.
  28.  
  29.   Function  GetEnvironment   Return the value associated with a
  30.                              specified keyword in the DOS environment
  31.                              string.  A zero-length returned value means
  32.                              the keyword was not found.
  33.  
  34.   Function  GetVector        Return a pointer to an interrupt routine.
  35.  
  36.   Procedure SetVector        Set an interrupt vector to the address
  37.                              specified in a pointer variable.
  38.  
  39.   Function  GetVerify        Return a boolean value reporting the
  40.                              current state of the disk-verify switch:
  41.                              on=true, off=false.
  42.  
  43.   Procedure SetVerify        Turn the disk-verify switch on/off based
  44.                              on a boolean parameter: on=true, off=false.
  45.  
  46.   Function  FreeDiskSpace    Return a real number containing the number
  47.                              of bytes available on a specified disk
  48.                              drive letter.
  49.  
  50.   Function  AvailableMemory  Return a real number containing the size of
  51.                              the largest memory block available OUTSIDE
  52.                              of the Turbo Pascal program's space.
  53.  
  54.   Function  LoadAndExecute   Load and executes a program, passing a
  55.                              command-line parameter, and returning the
  56.                              program's DOS termination error-level code
  57.                              as an integer.  WARNING: Adjust the maximum
  58.                              stack size at compile-time to allow enough
  59.                              memory for the loaded program!
  60.  
  61.   Procedure ExecuteCommand   Execute a specified DOS command or, if a
  62.                              zero-length command is entered, exit to a
  63.                              secondary copy of COMMAND.COM (Enter an
  64.                              EXIT command to return to the Turbo Pascal
  65.                              program.)  WARNING: Adjust the maximum
  66.                              stack size at compile-time allow enough
  67.                              memory for COMMAND.COM!
  68.  
  69.   Function  FindFirstFile    Return a 12-byte string (filename.ext) that
  70.                              contains the name of the first file
  71.                              matching a specified file-search pattern
  72.                              ([d:][\dir\]name.ext) and attribute byte
  73.                              qualification.  File-search patterns may
  74.                              contain wildcards.  Zero-length return
  75.                              values indicate no match on the pattern.
  76.  
  77.   Function  FindNextFile     Return a 12-byte string (filename.ext) that
  78.                              contains the name of the NEXT matching file
  79.                              after the one found by FindFirstFile or a
  80.                              previous FindNextFile call.  There are no
  81.                              input parameters.
  82.  
  83.   Function  GetFileTime      Returns an 8-byte string (hh:mm:ss) that
  84.                              contains the create/update time of the file
  85.                              last found by FindFirstFile/FindNextFile.
  86.  
  87.   Function  GetFileDate      Returns a 10-byte string (mm/dd/yyyy) that
  88.                              contains the create/update date of the file
  89.                              last found by FindFirstFile/FindNextFile.
  90.  
  91.   Function  GetFileTime      Returns a real number that contains the
  92.                              number of bytes in the file last found by
  93.                              FindFirstFile/FindNextFile.
  94.  
  95. ------------------------------------------------------------------------
  96.  
  97.   Written and placed in the public domain by:
  98.  
  99.                            Glen F. Marshall
  100.                            1006 Gwilym Circle
  101.                            Berwyn, PA 19312
  102.  
  103. ***********************************************************************}
  104.  
  105. type { commonly used definitions for MsDos procedures and functions }
  106.  
  107.   AsciizInput      = string[255];
  108.   AsciizOutput     = array[1..256] of char;
  109.   MemoryAddress    = ^byte;
  110.   CommandLine      = string[127];
  111.  
  112. var  { commonly used MsDos interface parameter }
  113.  
  114.   MsDosRegs: record case integer of
  115.                1: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags: integer);
  116.                2: (AL, AH, BL, BH, CL, CH, DL, DH: byte);
  117.              end;
  118.  
  119. procedure Asciiz(S: AsciizInput; var R: AsciizOutput);
  120. { Common internal procedure: Convert a string to "ASCIIZ" format. }
  121.   begin
  122.     inline($1E/$16/$1F/$8D/$76/$08/$30/$ED/$8A/$0C/$46/$C4/$7E/$04/$F3/
  123.            $A4/$26/$88/$0D/$1F);
  124.   end {Asciiz};
  125.  
  126. procedure MsDosError;
  127. { Common internal procedure: Report a DOS error and abort the program. }
  128.   begin
  129.     with MsDosRegs do
  130.     begin
  131.       writeln('Abort - DOS Error #',AX);
  132.       halt;
  133.     end;
  134.   end {MsDosError};
  135.   
  136. const { file attribute bit values }
  137.  
  138.   FileReadOnly     = 1;
  139.   FileHidden       = 2;
  140.   FileSystem       = 4;
  141.   FileVolumeLabel  = 8;
  142.   FileSubdirectory = 16;
  143.   FileArchive      = 20;
  144.  
  145. function GetAttribute(FileName: AsciizInput): byte;
  146.   var
  147.     FileNameAsciiz: AsciizOutput;
  148.   begin
  149.     Asciiz(FileName, FileNameAsciiz);
  150.     with MsDosRegs do
  151.     begin
  152.       AX := $4300;
  153.       DS := seg(FileNameAsciiz);
  154.       DX := ofs(FileNameAsciiz);
  155.       MsDos(MsDosRegs);
  156.       if (Flags and 1) <> 0 then MsDosError;
  157.       GetAttribute := CX;
  158.     end;
  159.   end {GetAttribute};
  160.  
  161. procedure SetAttribute(FileName: AsciizInput; Attribute: byte);
  162.   var
  163.     FileNameAsciiz: AsciizOutput;
  164.   begin
  165.     Asciiz(FileName, FileNameAsciiz);
  166.     with MsDosRegs do
  167.     begin
  168.       AX := $4301;
  169.       DS := seg(FileNameAsciiz);
  170.       DX := ofs(FileNameAsciiz);
  171.       CX := Attribute;
  172.       MsDos(MsDosRegs);
  173.       if (Flags and 1) <> 0 then MsDosError;
  174.     end;
  175.   end {SetAttribute};
  176.  
  177. function GetBreak: boolean;
  178.   begin
  179.     with MsDosRegs do
  180.     begin
  181.       AX := $3300;
  182.       MsDos(MsDosRegs);
  183.       GetBreak := (DL = 1);
  184.     end;
  185.   end {GetBreak};
  186.  
  187. procedure SetBreak(Sw: boolean);
  188.   begin
  189.     with MsDosRegs do
  190.     begin
  191.       AX := $3301;
  192.       if sw then DL := 1
  193.             else DL := 0;
  194.     end;
  195.     MsDos(MsDosRegs);
  196.   end {SetBreak};
  197.  
  198. function GetDTA: MemoryAddress;
  199.   begin
  200.     with MsDosRegs do
  201.     begin
  202.       AH := $2F;
  203.       MsDos(MsDosRegs);
  204.       GetDTA := ptr(ES,BX);
  205.     end;
  206.   end {GetDTA};
  207.  
  208. procedure SetDTA(DTA: MemoryAddress);
  209.   begin
  210.     with MsDosRegs do
  211.     begin
  212.       AH := $1A;
  213.       DS := seg(DTA^);
  214.       DX := ofs(DTA^);
  215.     end;
  216.     MsDos(MsDosRegs);
  217.   end {SetDTA};
  218.  
  219. function GetEnvironment(Keyword: CommandLine): CommandLine;
  220.   var
  221.     EnvSeg, i, j: integer;
  222.     s: CommandLine;
  223.   begin
  224.     EnvSeg := memw[Cseg:$2C];
  225.     i := 0;
  226.     s[0] := #0;
  227.     while (mem[EnvSeg:i] <> 0) and (s[0] = #0) do
  228.     begin
  229.       j := 0;
  230.       while mem[EnvSeg:i+j] <> 0 do
  231.       begin
  232.         s[j+1] := chr(mem[EnvSeg:i+j]);
  233.         j := succ(j);
  234.       end;
  235.       s[0] := chr(j);
  236.       i := succ(i + j);
  237.       if pos(Keyword+'=',s) = 1 then
  238.         delete(s,1,length(keyword)+1)
  239.       else
  240.         s[0] := #0;
  241.     end;
  242.     GetEnvironment := s;
  243.   end {GetEnvironment};
  244.  
  245. function GetVector(Interrupt: byte): MemoryAddress;
  246.   begin
  247.     with MsDosRegs do
  248.     begin
  249.       AH := $35;
  250.       AL := Interrupt;
  251.       MsDos(MsDosRegs);
  252.       GetVector := ptr(ES,BX);
  253.     end;
  254.   end {GetVector};
  255.  
  256. procedure SetVector(Interrupt: byte; Vector: MemoryAddress);
  257.   begin
  258.     with MsDosRegs do
  259.     begin
  260.       AH := $25;
  261.       AL := Interrupt;
  262.       DS := seg(Vector^);
  263.       DX := ofs(Vector^);
  264.     end;
  265.     MsDos(MsDosRegs);
  266.   end {SetVector};
  267.  
  268. function GetVerify: boolean;
  269.   begin
  270.     with MsDosRegs do
  271.     begin
  272.       AH := $54;
  273.       MsDos(MsDosRegs);
  274.       GetVerify := (AL = 1);
  275.     end;
  276.   end {GetVerify};
  277.  
  278. procedure SetVerify(Sw: boolean);
  279.   begin
  280.     with MsDosRegs do
  281.       if Sw then AX := $2E01
  282.             else AX := $2E00;
  283.     MsDos(MsDosRegs);
  284.   end {SetVerify};
  285.  
  286. function FreeDiskSpace(Drive: char): real;
  287.   begin
  288.     with MsDosRegs do
  289.     begin
  290.       AH := $36;
  291.       DL := ord(upcase(Drive))-64;
  292.       MsDos(MsDosRegs);
  293.       if AX = $FFFF then
  294.         FreeDiskSpace := -1
  295.       else
  296.         FreeDiskSpace := int(AX) * int(BX) * int(CX);
  297.     end;
  298.   end {FreeDiskSpace};
  299.  
  300. function AvailableMemory: real;
  301.   begin
  302.     with MsDosRegs do
  303.     begin
  304.       AH := $48;
  305.       BX := $A000;
  306.       MsDos(MsDosRegs);
  307.       if (Flags and 1) = 0 then
  308.       begin
  309.         AH := $49;
  310.         BX := $A000;
  311.         MsDos(MsDosRegs);
  312.         BX := $A000;
  313.       end
  314.       else
  315.         if AX <> 8 then MsDosError;
  316.       AvailableMemory := (int(BX and $7FFF)+32768.0*int(BX shr 15))*16;
  317.     end;
  318.   end {AvailableMemory};
  319.  
  320. function LoadAndExecute(ProgName, Parameter: CommandLine): integer;
  321.   const
  322.     SavedSS: integer = 0;
  323.     SavedSP: integer = 0;
  324.   var
  325.     ProgNameAsciiz : AsciizOutput;
  326.     ExecBlock      : record
  327.                        EnvSeg      : integer;
  328.                        CommandAddr : MemoryAddress;
  329.                        FcbAddr1    : MemoryAddress;
  330.                        FcbAddr2    : MemoryAddress;
  331.                      end;
  332.     MsDosReturn    : integer;
  333.  
  334.   begin
  335.     Asciiz(ProgName, ProgNameAsciiz);
  336.     with ExecBlock do
  337.     begin
  338.       EnvSeg      := memw[Cseg:$2C];
  339.       CommandAddr := addr(Parameter);
  340.       FcbAddr1    := ptr(Cseg,$5C);
  341.       FcbAddr2    := ptr(Cseg,$6C);
  342.     end;
  343.     with MsDosRegs do
  344.     begin
  345.       AX := 0;
  346.       inline($1E/$55/$8C/$D0/$2E/$A3/SavedSS/$2E/$89/$26/SavedSP/$8E/
  347.              $D8/$8E/$C0/$8D/$96/ProgNameAsciiz/$8D/$9E/ExecBlock/$B8/
  348.              $00/$4B/$CD/$21/$FA/$2E/$8E/$16/SavedSS/$2E/$8B/$26/
  349.              SavedSP/$FB/$5D/$1F/$73/03/$A3/MsDosRegs);
  350.       if AX <> 0 then MsDosError;
  351.       AH := $4D;
  352.       MsDos(MsDosRegs);
  353.       LoadAndExecute := AX;
  354.     end;
  355.   end {LoadAndExecute};
  356.  
  357. procedure ExecuteCommand(Command: CommandLine);
  358.   var
  359.     Comspec: CommandLine;
  360.     i: integer;
  361.   begin
  362.     Comspec := GetEnvironment('COMSPEC');
  363.     if length(Command) > 0 then
  364.       i := LoadAndExecute(Comspec,'/C '+Command+#13)
  365.     else
  366.       i := LoadAndExecute(Comspec,'');
  367.   end {ExecuteCommand};
  368.  
  369. type { common definition used by file functions below }
  370.  
  371.   FileSpec         = string[12];
  372.  
  373.   FileTimeDate     = record
  374.                        FileTime      : integer;
  375.                        FileDate      : integer;
  376.                      end;
  377.  
  378.   DisplayFileTime  = string[8];
  379.  
  380.   DisplayFileDate  = string[10];
  381.  
  382.   FileSizeLoHi     = record
  383.                        FileSizeLo    : integer;
  384.                        FileSizeHi    : integer;
  385.                      end;
  386.  
  387.   DisplayFileSize  = string[8];
  388.  
  389.   FindFileWorkArea = record
  390.                        reserved      : array[0..20] of byte;
  391.                        FileAttribute : byte;
  392.                        FileTimeStamp : FileTimeDate;
  393.                        FileSize      : FileSizeLoHi;
  394.                        FileName      : array[1..13] of char;
  395.                      end;
  396.  
  397. var  { common storage structure used by file-find function below }
  398.  
  399.   FindFileDTA      : FindFileWorkArea;
  400.  
  401. function FindFirstFile(FileParam: AsciizInput;
  402.                        AttributeParam: byte): FileSpec;
  403.   var
  404.     SavedDTA: MemoryAddress;
  405.     FileParamAsciiz: AsciizOutput;
  406.   begin
  407.     SavedDTA := GetDTA;
  408.     SetDTA(addr(FindFileDTA));
  409.     Asciiz(FileParam,FileParamAsciiz);
  410.     with MsDosRegs do
  411.     begin
  412.       AH := $4E;
  413.       DS := seg(FileParamAsciiz);
  414.       DX := ofs(FileParamAsciiz);
  415.       CX := AttributeParam;
  416.       MsDos(MsDosRegs);
  417.       if AX = 0 then
  418.         with FindFileDTA do
  419.           FindFirstFile := copy(FileName,1,Pos(#0,FileName)-1)
  420.       else
  421.         FindFirstFile := '';
  422.     end;
  423.     SetDTA(SavedDTA);
  424.   end {FindFirstFile};
  425.  
  426. function FindNextFile: FileSpec;
  427.   var
  428.     SavedDTA: MemoryAddress;
  429.   begin
  430.     SavedDTA := GetDTA;
  431.     SetDTA(addr(FindFileDTA));
  432.     with MsDosRegs do
  433.     begin
  434.       AH := $4F;
  435.       MsDos(MsDosRegs);
  436.       if AX = 0 then
  437.         with FindFileDTA do
  438.           FindNextFile := copy(FileName,1,pos(#0,FileName)-1)
  439.       else
  440.         FindNextFile := '';
  441.     end;
  442.     SetDTA(SavedDTA);
  443.   end {FindFirstFile};
  444.  
  445. function GetFileTime: DisplayFileTime;
  446.   var
  447.     hs,ms,ss: string[2];
  448.   begin
  449.     with FindFileDTA do
  450.       with FileTimeStamp do
  451.       begin
  452.         str((FileTime shr 11):2,hs);
  453.         if hs[1] = ' ' then hs[1] := '0';
  454.         str(((FileTime shr 5) and 63):2,ms);
  455.         if ms[1] = ' ' then ms[1] := '0';
  456.         str(((FileTime shl 1) and 63):2,ss);
  457.         if ss[1] = ' ' then ss[1] := '0';
  458.       end;
  459.     GetFileTime := hs+':'+ms+':'+ss;
  460.   end {GetFileTime};
  461.  
  462. function GetFileDate: DisplayFileDate;
  463.   var
  464.     ys: string[4];
  465.     ms,ds: string[2];
  466.   begin
  467.     with FindFileDTA do
  468.       with FileTimeStamp do
  469.       begin
  470.         str(((FileDate shr 9)+1980):4,ys);
  471.         str(((FileDate shr 5) and 15):2,ms);
  472.         if ms[1] = ' ' then ms[1] := '0';
  473.         str((FileDate and 31):2,ds);
  474.         if ds[1] = ' ' then ds[1] := '0';
  475.       end;
  476.     GetFileDate := ms+'/'+ds+'/'+ys;
  477.   end {GetFileDate};
  478.  
  479. function GetFileSize: real;
  480.   begin
  481.     with FindFileDTA do
  482.       with FileSize do
  483.         GetFileSize := int(FileSizeLo and $7FFF) +
  484.                        32768.0 * int(FileSizeLo shr 15) +
  485.                        65536.0 * int(FileSizeHi);
  486.   end {GetFileSize};
  487.