home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / basic / qlib / disk.doc < prev    next >
Text File  |  1993-10-11  |  30KB  |  831 lines

  1.     DISK / FILE routines look for specified files on your disk, or report
  2.     disk status.  Several QLIB disk/file subroutines return the following
  3.     error codes:
  4.  
  5.          1 = file name is a nul string
  6.          2 = file not found
  7.          3 = path not found
  8.          4 = too many open files
  9.          5 = access denied (file may be read-only or a subdirectory,
  10.                             or subdirectory not empty)
  11.          6 = handle invalid
  12.          8 = insufficient memory
  13.         15 = invalid drive
  14.         19 = disk is write-protected
  15.     &HFFFF = input past end of file
  16.  
  17.  
  18.     File attributes may be combined.  Each bit of a file attribute means:
  19.  
  20.          0 = normal files
  21.          1 = read-only
  22.          2 = hidden files
  23.          4 = system files
  24.          8 = volume label (only one per disk - may not be
  25.                            reliable)
  26.         16 = subdirectories
  27.         32 = archive bit set
  28.  
  29.      Thus a file attribute of 18 is a hidden subdirectory (16 OR 2)
  30.  
  31.      Note that QLIB subroutines no longer require zero-terminated filenames.
  32.  
  33.      QLIB's Input/Output subroutines provide fast, flexible file handling,
  34.      replacing BASIC's clumsy functions.  These subroutines return an error
  35.      code in QLIB's DOSError flag if something went wrong.
  36.  
  37.      Summary of QLIB's file I/O subroutines:
  38.  
  39.      FOpen       Open an existing file
  40.      FCreate     Make a new file and open it for output
  41.      FClose      Close a file opened by FOpen or FCreate
  42.  
  43.      FGet1       Read one byte from a file opened by FOpen
  44.      FGet2       Read 2 bytes from a file opened by FOpen
  45.      FGet4       Read 4 bytes from a file opened by FOpen
  46.      FGet8       Read 8 bytes from a file opened by FOpen
  47.      FGet        Read from a file opened by FOpen to an array
  48.      FGetSTR     Read an ASCII string from a file opened by FOpen
  49.  
  50.      FPut1       Write one byte to a file
  51.      FPut2       Write 2 bytes to a file
  52.      FPut4       Write 4 bytes to a file
  53.      FPut8       Write 8 bytes to a file
  54.      FPut        Write data to a file directly from an array
  55.      FPutSTR     Write an ASCII string to a file
  56.      FPutCRLF    Write CR+LF to a file
  57.  
  58.      FSeek       moves the file pointer forward or backward in the file
  59.      FFlush      flushes the QLIB and DOS output file buffers
  60.  
  61.  
  62.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  63.  
  64.      Subroutine: DiskInfo(d$, sect%, avail%, bytes%, clust%)
  65.  
  66.           Determines disk information for disk in specified drive.
  67.      D$ is the drivespec, i. e., D$ = "A:", sect% is sectors per cluster,
  68.      avail% = available clusters, bytes% = bytes per sector, and clust% =
  69.      total clusters on disk.
  70.  
  71.      Example:
  72.         d$ = "a:"
  73.         CALL diskinfo(d$, a, b, c, d)
  74.         ' a = sectors/cluster
  75.         ' b = avail clusters
  76.         ' c = bytes/sector
  77.         ' d = drive clusters
  78.         PRINT a, b, c, d
  79.  
  80.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  81.  
  82.      Function: driveerror% = DiskWP (drive%)
  83.      object file: diskwp.obj
  84.  
  85.           DiskWP determines if a floppy disk is ready and whether it
  86.      is write protected or not.  Supports physical drives A: and B:.
  87.  
  88.      driveerror% returned by DiskWP is a BIOS error code:
  89.  
  90.                 0 = no error
  91.                 1 = invalid disk number
  92.                 2 = disk not readable (not formatted, or wrong type)
  93.                 3 = disk is write-protected
  94.               128 = drive not ready
  95.  
  96.      Example:
  97.           REM $INCLUDE: 'qlib.bi'
  98.           drive% = 0              ' drive A:
  99.                                   ' drive% = 1 for drive B:
  100.           driveerror% = DiskWP (drive%)
  101.           IF driveerror% THEN ... ' oops, problem
  102.  
  103.  
  104.  
  105.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  106.  
  107.      Subroutine: DotBAK (filename$)
  108.      object files: dotbak.obj ($asciiz.obj, strrchr.obj, strlen.obj)
  109.  
  110.           DotBAK changes the name of an existing filename.ext to
  111.      filename.BAK.  If filename.BAK already exists, it is deleted before
  112.      filename.ext is renamed.  DotBAK updates the DOSError flag in case of
  113.      errors.
  114.  
  115.      Example:
  116.           REM $INCLUDE: 'qlib.bi'   ' has function declaration for DOSError
  117.  
  118.           REM I want to save an old data file DATA.DAT as a backup file
  119.           REM before writing a new DATA.DAT file.
  120.  
  121.           filename$ = "DATA.DAT"
  122.           CALL  DotBAK (filename$)  ' change existing DATA.DAT to DATA.BAK
  123.           IF DOSError THEN ...      ' in case of errors
  124.  
  125.  
  126.  
  127.  
  128.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  129.  
  130.      Subroutine: DriveSpace(drv$, total&, free&, oops%)
  131.      object file: drvspace.obj
  132.  
  133.           Returns the amount of total and free space left on a given disk
  134.      drive.  The drive string may be any legal disk drive, or "@" (AT sign)
  135.      for the default drive, and must be at least one character long.  An
  136.      illegal drive or other error will cause oops% to be returned as -1.
  137.      Note that total& and free& are LONG integers.  Works with logical
  138.      devices up to 2,147 Megabytes.
  139.  
  140.      Example:
  141.           drv$="C:"
  142.            .
  143.            .
  144.           CALL DriveSpace(drv$, total&, free&, oops%)
  145.           IF oops% = -1 THEN
  146.                   PRINT "Invalid drive specification"
  147.                   ELSE
  148.                   PRINT "Free space on drive "; drv$; " is"; free&; "bytes."
  149.                   PRINT "Total space on drive "; drv$; " is"; total&; "bytes."
  150.           END IF
  151.  
  152.  
  153.  
  154.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  155.  
  156.      Subroutine: Exist(filename$, oops%)
  157.      object file: exist.obj ($asciiz.obj)
  158.  
  159.           Tells you if a given file already exists.  Returns an error code
  160.      if it doesn't, or -1 if it does.  The filename must not include any
  161.      "?" or "*" wildcard characters.
  162.  
  163.      Example:
  164.        filename$="QLIB.QLB"
  165.        CALL Exist(filename$, oops%)
  166.        IF oops% = -1 THEN PRINT "File already exists"
  167.        IF oops% = 0 THEN PRINT "Path exists"
  168.                                   ' Filename$ = "d:\path"
  169.        IF oops% = 2 THEN PRINT "Path found, file not found"
  170.        IF oops% = 3 THEN PRINT "Path or file not found"
  171.  
  172.  
  173.  
  174.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  175.  
  176.      Subroutine: FClose(handle%)
  177.      object file: fopen.obj
  178.  
  179.          Closes a file opened by FOpen or FCreate.  Handle% is the file
  180.      handle returned by FOpen.  FClose updates the DOSError flag.
  181.  
  182.      Example:
  183.          CALL FClose(handle%)
  184.  
  185.  
  186.  
  187.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  188.  
  189.      Subroutine: FCopy(FromFile$, ToFile$)
  190.      object file: fcopy.obj (q$alloc.obj, q$error.obj)
  191.  
  192.           Copies a file from FromFile$ to ToFile$, and updates DOSError
  193.      with an error code if something went wrong.  FromFile$ and ToFile$
  194.      may not include any wildcard characters (such as * and ?).  FCopy
  195.      will destroy any previously-existing file named ToFile$ before
  196.      copying the file.
  197.  
  198.      Example:
  199.           REM $INCLUDE: 'qlib.bi'
  200.  
  201.           FromFile$ = "b:\qlib.lib"
  202.           ToFile$ = "c:\qb4\qlib.lib"
  203.           CALL FCopy(FromFile$, ToFile$)
  204.           IF DOSError THEN ...                ' check for errors
  205.  
  206.  
  207.  
  208.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  209.  
  210.      Function: handle% = FCreate(file$)
  211.      object file: fopen.obj ($asciiz.obj)
  212.  
  213.          Creates a new file and returns a handle for subsequent writing.
  214.      If the file already exists, it will be truncated to zero bytes by
  215.      FCreate.  FCreate updates DOSError.
  216.  
  217.      Example:
  218.          REM $INCLUDE: 'qlib.bi'
  219.          file$ = "anyold.dat"
  220.          mode% = 1                         ' access mode: write only
  221.          handle% = FOpen(file$,mode%)      ' first try to open an existing file
  222.          IF DOSError = 2 THEN
  223.             handle% = FCreate(file$)       ' create a new file if "anyold.dat"
  224.                                            ' is not found
  225.          ENDIF
  226.  
  227.  
  228.  
  229.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  230.  
  231.      Subroutine: FFlush (handle%)
  232.      object file: fflush.obj (fseek.obj, q$error.obj)
  233.  
  234.           Flushes the QLIB and DOS file output buffers associated with
  235.      handle%.  The file must have been opened with QLIB's FOpen or FCreate
  236.      functions.  Flushing the file buffer protects against unintended system
  237.      failures such as power outages.  Any data written to the file before
  238.      calling FFlush will be safely written to the disk.  FFlush also updates
  239.      QLIB's DOSError flag.
  240.  
  241.      Example:
  242.        REM $INCLUDE: 'qlib.bi'
  243.        f$ = "anyold.fil"
  244.        handle% = FCreate (f$)
  245.        ' program writes data to the file
  246.        .
  247.        .
  248.        .
  249.        CALL FFlush (handle%)
  250.        IF DOSError THEN ...           ' check for errors
  251.  
  252.  
  253.  
  254.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  255.  
  256.      Subroutine: FGet(handle%, aSEG%, aPTR%, bytes%)
  257.      object file: fget.obj ($handle.obj, q$fget.obj, $fget.obj)
  258.  
  259.          Reads bytes% bytes of data from a file opened by FOpen and
  260.      loads the data into an array beginning at the address pointed to
  261.      by aSEG% and aPTR%.  FGet updates the DOSError flag in case of errors.
  262.      Bytes% may be as large as 32,767.  If you want to read more (up to
  263.      65,535 bytes) use a LONG integer bytes& instead of bytes%.
  264.  
  265.      Example:
  266.         REM $INCLUDE: 'qlib.bi'
  267.         DIM a(99)
  268.         bytes% = 200                                  ' 2 bytes per integer
  269.         file$ = "anyold.dat": mode% = 0               ' read-only
  270.         handle% = FOpen(file$, mode%)                 ' open file
  271.         aSEG% = VARSEG(a(0))                          ' start at beginning
  272.         aPTR% = VARPTR(a(0))
  273.         CALL FGet(handle%, aSEG%, aPTR%, bytes%)
  274.         IF DOSError THEN ...                          ' check for errors
  275.  
  276.      You can also declare FGet as a function to return the number of bytes
  277.      actually read from the file:
  278.  
  279.      Example 2:
  280.         REM $INCLUDE: 'qlib.bi'
  281.         REM  declare FGet as a function, allowing bytes to be either
  282.         REM  INTEGER or LONG
  283.         DECLARE FUNCTION FGet&(h%, s%, p%, b AS ANY)
  284.         DIM a(99)
  285.         bytes% = 200                                  ' 2 bytes per integer
  286.         file$ = "anyold.dat": mode% = 0               ' read-only
  287.         handle% = FOpen(file$, mode%)                 ' open file
  288.         aSEG% = VARSEG(a(0))                          ' start at beginning
  289.         aPTR% = VARPTR(a(0))
  290.         bytes& = FGet(handle%, aSEG%, aPTR%, bytes%)
  291.         IF DOSError THEN ...                          ' check for errors
  292.         IF bytes& <> 200 THEN ...
  293.  
  294.  
  295.  
  296.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  297.  
  298.      Subroutine: FGet1(handle%, n%)
  299.      object file: fget1.obj
  300.  
  301.      Subroutine: FGet2(handle%, n%)
  302.      object file: fget2.obj
  303.  
  304.      Subroutine: FGet4(handle%, n& [or n!])
  305.      object file: fget4.obj
  306.  
  307.      Subroutine: FGet8(handle%, n#)
  308.      object file: fget8.obj
  309.  
  310.         FGet[n] subroutines write a single data point to the file opened
  311.      by FOpen.  FGet1 is intended for character or short integer data,
  312.      FGet2 is for INTEGER data, FGet4 is for LONG or SINGLE data and
  313.      FGet8 is for DOUBLE, CURRENCY or QLIB's COMPLEX data.  Note that
  314.      SINGLE or DOUBLE data may be either IEEE format or Microsoft Binary
  315.      Format.  FGet subroutines update the DOSError flag in case of errors.
  316.  
  317.      Example:
  318.           REM $INCLUDE: 'qlib.bi'
  319.  
  320.           handle% = FOpen(file$,0)
  321.               .
  322.               .
  323.               .
  324.           CALL FGet4(handle%, n&)
  325.           IF DOSError THEN  ...            ' check for errors
  326.  
  327.  
  328.  
  329.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  330.  
  331.      Function: s$ = FGetSTR$(handle%)
  332.      object file: fgetstr.obj ($handle.obj, $fget.obj)
  333.  
  334.          FGetSTR reads an ASCII string of up to 4094 bytes from the file
  335.      associated with handle%.  FGetSTR updates the DOSError flag in case
  336.      of errors.
  337.  
  338.      Example:
  339.          REM $INCLUDE: 'qlib.bi'
  340.          mode% = 0                     ' read only
  341.          handle% = FOpen("input.dat", mode%)
  342.          IF DOSError THEN PRINT "Error opening file":END
  343.          WHILE NOT DOSError
  344.            s$ = FGetSTR(handle)
  345.            PRINT s$
  346.          WEND
  347.  
  348.  
  349.  
  350.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  351.  
  352.      Function: count% = FileCount(s$, attr%)
  353.      object file: findfile.obj ($asciiz.obj)
  354.  
  355.           Counts the number of files matching the filespec s$.  S$ may
  356.      include the wildcard characters * and ?.
  357.  
  358.      Example:
  359.        REM $INCLUDE: 'qlib.bi'
  360.        s$ ="*.*"        ' count all files in the current directory
  361.        attr% = 0        ' normal files only
  362.        count% = FileCount(s$, attr%)
  363.  
  364.  
  365.  
  366.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  367.  
  368.     Function: fseg% = FLoad (filename$)
  369.     object files: fload.obj (q$alloc.obj, q$error.obj, $asciiz.obj)
  370.  
  371.     FLoad reads a specified file into far memory, returning the segment
  372.     address of the memory block where the file is located.  If an error
  373.     occurs when reading the file, FLoad returns fseg% = 0.  QLIB's
  374.     DOSError flag is also updated (see DOSError in SYSTEM.DOC).
  375.     If no error occurred, DOSError returns 0; otherwise it returns an
  376.     MS-DOS error code.  If fseg% = 0 and DOSError = 0 then insufficient
  377.     far memory is available.  To release the memory allocated by this
  378.     function, use FreeMem(fseg%).  See DATA.DOC.
  379.  
  380.     Example:
  381.      REM $INCLUDE: '\qb4\qlib.bi'
  382.      filename$ = "\ramfont\italics.fnt"
  383.      iseg% = fload (filename$)
  384.      IF DOSError THEN
  385.          .
  386.          .
  387.          .              ; error handling code
  388.  
  389.  
  390.  
  391.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  392.  
  393.      Function: handle% = FOpen(file$, mode%)
  394.      object file: fopen.obj, $handle.obj
  395.  
  396.          FOpen opens an existing file for input, output or random I/O.
  397.      Access mode is 0 for read only, 1 for write only and 2 for read/write
  398.      access.  File$ is any valid file name.  Handle% is the file handle
  399.      returned by FOpen for use with subsequent input from or output to the
  400.      file.  When a file is opened by FOpen, the MS-DOS file pointer is
  401.      positioned at the start of the file.  Use FSeek to position the
  402.      pointer at the end of the file, for appending the file.  FOpen
  403.      updates the DOSError flag if there was a problem.
  404.  
  405.      Example:
  406.         REM $INCLUDE: 'qlib.bi'
  407.         File$ = "anyold.fil"
  408.         mode% = 0                     ' read only
  409.         handle% = FOpen(file$, mode%)
  410.         IF DOSError THEN ...          ' check for error
  411.  
  412.  
  413.  
  414.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  415.  
  416.      Subroutine: FPut(handle%, ArraySegment%, ArrayPointer%, bytes%)
  417.      object file: fput.obj ($handle.obj, q$fput.obj)
  418.  
  419.          Writes data directly from an array to a file.  The file must have
  420.      been opened by QLIB's FOpen in write or read/write mode, or by FCreate.
  421.      Up to 65,535 bytes may be written each time FPut is called; for more
  422.      than 32,767 bytes, use a LONG integer (bytes&) instead of bytes%.
  423.      FPut updates the DOSError flag if someting went wrong.
  424.  
  425.      Example:
  426.         REM $INCLUDE: 'qlib.bi'    ' FOpen and FCreate function declarations
  427.         DIM a&(599)                ' 600 long integers
  428.         .
  429.         .
  430.         .                          ' program establishes values of the data
  431.         filename$ = "longint.dat"
  432.         CALL DotBAK(filename$)     ' rename previous file to "longint.bak"
  433.         h = FCreate(filename$)     ' new "longint.dat"
  434.  
  435.         IF DOSError THEN PRINT "Can't open output file": GOTO FileError
  436.         s = VARSEG(a&(0)): p = VARPTR(a&(0)): n = 2400
  437.         CALL FPut(h, s, p, n)
  438.  
  439.  CloseFile:
  440.         CALL FClose(h)
  441.         .
  442.         .
  443.  
  444.  REM  jump here if there was a problem creating the file
  445.  FileError:
  446.         .
  447.         .
  448.  
  449.  
  450.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  451.  
  452.      Subroutine: FPut1(handle%, n%)
  453.      Subroutine: FPut2(handle%, n%)
  454.      Subroutine: FPut4(handle%, n& [or n!])
  455.      Subroutine: FPut8(handle%, n# [or n@])
  456.      object file: fput1.obj (q$fput.obj)
  457.  
  458.      Similar to FGet[], above, but writes data to the file.  The file
  459.      should have been opened with FOpen (write or read/write mode) or
  460.      by FCreate.  FPut[] subroutines leave an error code in the DOSError
  461.      flag if something went wrong.
  462.  
  463.      FPut1 writes a single byte or character
  464.      FPut2 writes a 2-byte INTEGER
  465.      FPut4 writes 4 bytes of data, such as a LONG or SINGLE value
  466.      FPut8 writes 8 bytes of data, such as DOUBLE or CURRENCY values
  467.  
  468.  
  469.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  470.  
  471.      Subroutine: FPutCRLF(handle%)
  472.      object file: fputcrlf.obj ($handle.obj, q$fput.obj)
  473.  
  474.      Subroutine: FPutSTR(handle%, s$)
  475.      object file: fputstr.obj ($handle.obj, q$fput.obj)
  476.  
  477.          FPutSTR writes a string to an output file, updating the DOSError
  478.      flag if something went wrong.  FPutSTR does not write CR+LF at the
  479.      end of the string; use FPutCRLF to write to the next line in the file.
  480.  
  481.      Example:
  482.          REM $INCLUDE: 'qlib.bi'
  483.          REM  I want to copy "input.dat" to "output.dat"
  484.          REM  while filtering out references to "stupid boss"
  485.  
  486.          stupid$ = "stupid boss"
  487.          inhandle = FOpen("input.dat", 0)                  ' read only
  488.          IF DOSError THEN PRINT "Error opening input file":END
  489.          outhandle = FOpen("output.dat", 1)                ' write only
  490.          IF DOSError THEN PRINT "Error opening output file":END
  491.          WHILE NOT DOSError
  492.            s$ = FGetSTR(inhandle)
  493.            IF DOSError GOTO EndOfFile
  494.            IF INSTR(s$, stupid$) = 0 THEN
  495.                 CALL FPutSTR(outhandle, s$)
  496.                 CALL FPutCRLF(outhandle)
  497.            ENDIF
  498.          WEND
  499. EndOfFile:
  500.          CALL FClose(inhandle)
  501.          CALL FCLose(outhandle)
  502.  
  503.  
  504.  
  505.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  506.  
  507.      Subroutine: FSeek(handle%, bytes&, seekmode%)
  508.      object file: fseek.obj ($handle.obj)
  509.  
  510.          Moves the file pointer from its present position forward or
  511.      backward in the file.  The file must have been opened by FOpen
  512.      or FCreate.  Bytes& is the number of bytes to move the pointer.
  513.  
  514.      Seekmode% = 0 if bytes& is absoute offset from start of file
  515.                = 1 if bytes& is signed offset from current file pointer
  516.                = 2 if bytes& is signed offset from end of file
  517.  
  518.      Example:
  519.          CALL FSeek(handle%, bytes&, seekmode%)
  520.  
  521.  
  522.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  523.  
  524.      Function: s& = FSize (handle%)
  525.      object file: fsize.obj (d$error.obj)
  526.  
  527.           Given a valid file handle returned by a QLIB FOpen
  528.      subroutine, FSize returns the size of the file.  Any DOS errors
  529.      are flagged by DOSError (see DOSError in SYSTEM.DOC).
  530.  
  531.      Example:
  532.          REM $INCLUDE: 'qlib.bi'
  533.          handle% = FOpen(file$, mode%)
  534.          IF DOSError THEN . . .       ' error control stuff
  535.          s& = FSize(handle%)
  536.          IF DOSError THEN . . .       ' error control stuff
  537.         
  538.  
  539.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  540.  
  541.      Function: d$ = GetDRIVE
  542.      object file: getdrive.obj
  543.  
  544.          Returns the default drive.
  545.  
  546.      Example:
  547.          REM $INCLUDE: 'qlib.bi'
  548.              .
  549.              .
  550.              .
  551.          drive$ = GetDRIVE
  552.          PRINT "The default drive is "; drive$
  553.          REM  drive$ includes the trailing colon, i.e., drive$ = "C:"
  554.  
  555.  
  556.  
  557.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  558.  
  559.      Function: sub$ = GetSUB(d$)
  560.      object file: getsub.obj ($asciiz.obj, strncpy.obj)
  561.  
  562.          Gets the current directory on disk d$.  To get the current
  563.      directory on the default drive, set d$ = "@".  If d$ specifies an
  564.      invalid drive, sub$ will be a nul string.  NOTE: d$ must be at least
  565.      one character long.
  566.  
  567.      Example:
  568.          REM $INCLUDE: 'qlib.bi'
  569.          d$ = "C:"
  570.          sub$ = GetSUB(d$)
  571.          IF sub$ = "" THEN PRINT d$ + " is not a valid drive"
  572.  
  573.  
  574.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  575.  
  576.     Subroutine: FindFirstMatch(file$, fAttr%, oops%)
  577.     Subroutine: FindNextMatch(oops%)
  578.     Subroutine: FindFileName(filename$, flen%)
  579.     Subroutine: FindFileAttr(fAttr%)
  580.     Subroutine: FindFileDate(month%, day%, year%)
  581.     Subroutine: FindFileTime(hour%, min%, sec%)
  582.     Subroutine: FindFileSize(lowword%, highword%)
  583.     object file: findfile.obj ($asciiz.obj)
  584.  
  585.          This group of subroutines may be used to search for files which match
  586.     a specified file name.  The specified file name may include drive and
  587.     path, and may also include the * and ? wildcards.  These subroutines may
  588.     be used to duplicate the DOS DIR command.
  589.  
  590.     A search attribute (fAttr%) may also be specified.  File attributes are
  591.     listed on the first page of this file.
  592.  
  593.     fAttr% may include more than one type of file.  For example, if
  594.     fAttr% = 2 + 8, FindFirst/NextMatch will search for hidden and system
  595.     files as well as normal files (normal files will always be found).
  596.     The actual file attribute of the matched file will be returned by
  597.     FindFileAttr.  Files returned may have a combination of attributes; for
  598.     example, if a file attribute returned by FindFileAttr is 18 ( = 2 + 16),
  599.     this file is a hidden directory.
  600.  
  601.     The file size returned by FindFileSize is in two parts.  Use the following
  602.     code to determine the file size:
  603.  
  604.     CALL FindFileSize(lowword%, highword%)  ' assumes file matched with
  605.                                             ' FindFirst/NextMatch, oops% <> 0
  606.     size& = CLNG(lowword%)
  607.     IF lowword% < 0 THEN size& = size& + 65536&
  608.     size& = size& + highword% * 65536&
  609.  
  610.     see examples on the next page
  611.  
  612.  
  613.     Example 1:
  614.          filename$ = SPACE$(12)             ' filename$ must be initialized
  615.                                             ' as a 12-byte (or longer) string
  616.                                             ' or the namelen% will be returned
  617.                                             ' as -1
  618.          FileSpec$ = "\qb4\*.bas"
  619.          fAttr% = 0                         ' search only for normal files
  620.          CALL FindFirstMatch(FileSpec$, fAttr%, oops%)
  621.          IF oops% = -1 THEN PRINT "FileSpec$ is a nul string"
  622.          IF oops% THEN PRINT "No matching files"
  623.          WHILE oops% = 0
  624.               CALL FindFileName(filename$, namelen%)
  625.               IF namelen% = -1 THEN PRINT "filename$ shorter than 12 bytes"
  626.               PRINT LEFT$(filename$, namelen%)
  627.               CALL FindNextMatch(oops%)
  628.          WEND
  629.          REM  FindFileName, FindFileAttr, FindFileDate, FindFileTime and
  630.          REM  FindFileSize will return usable results only after a successful
  631.          REM  (oops% = 0) call to FindFirstMatch or FindNextMatch.
  632.  
  633.     Example 2:
  634.          REM  In this example, we will print all subdirectories one
  635.          REM  level down from the root directory
  636.          filename$ = SPACE$(12)             ' filename$ must be initialized
  637.                                             ' as a 12-byte (or longer) string
  638.          fAttr% = 16
  639.          FileSpec$ = "\*.*"
  640.          CALL FindFirstMatch(FileSpec$, fAttr%, oops%)
  641.          IF oops% THEN PRINT "No files or subdirectories"
  642.          WHILE oops% = 0
  643.               CALL FindFileAttr(fAttr%)
  644.               IF fAttr% AND 16 THEN
  645.                    CALL FindFileName(filename$, namelen%)
  646.                    PRINT LEFT$(filename$, namelen%)
  647.               END IF
  648.               CALL FindNextMatch(oops%)
  649.          WEND
  650.  
  651.  
  652.  
  653.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  654.  
  655.     Subroutine: GetFileAttr(file$, attr%, oops%)
  656.     object file: fileattr.obj ($asciiz.obj)
  657.  
  658.          Returns the attribute of file$.  File$ must not include
  659.     any * or ? wildcards.  File attributes are listed on the first page
  660.     of this file.  Oops% is an MS-DOS error code if something went wrong,
  661.     or oops% = -1 if no problems were encountered.
  662.  
  663.     Example:
  664.          file$ = "c:\qb4\qlib.lib"
  665.          CALL GetFileAttr(file$, attr%, oops%)
  666.  
  667.  
  668.  
  669.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  670.  
  671.     Function: ok% = GoodDrive(d$)
  672.     object file: goodrive.obj
  673.  
  674.          GoodDrive determines if a logical drive is valid.  D$ is the drive
  675.     name, i. e., d$ = "A:", "B:", etc.  Ok% = 0 if the drive is not a valid
  676.     drive, or ok% = -1 if the drive is a logical device in the system.
  677.  
  678.     Example:
  679.          REM $INCLUDE: 'qlib.bi'
  680.  
  681.          REM determine names of logical devices
  682.  
  683.          FOR i = 0 to 25
  684.          d$ = CHR$(65 + i)
  685.          IF GoodDrive(d$) THEN PRINT d$
  686.          NEXT
  687.  
  688.  
  689.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  690.  
  691.     Subroutine: KillFile(file$, oops%)
  692.     object file: killfile.obj ($asciiz.obj)
  693.  
  694.          KillFile deletes file$ from a disk with error trapping, avoiding
  695.     BASIC's ON ERROR.  Oops% = 0 if no error; MS-DOS error codes apply if
  696.     oops% <> 0.
  697.  
  698.     Example:
  699.          file$ = "oldfile.dat"
  700.          CALL KillFile(file$, oops%)
  701.  
  702.  
  703.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  704.  
  705.     Subroutine: KillSUB(sub$, oops%)
  706.     object file: killfile.obj ($asciiz.obj)
  707.  
  708.          KillSUB deletes subdirectory sub$ from a disk with error trapping,
  709.     avoiding BASIC's ON ERROR.  The subdirectory must be empty before it is
  710.     deleted.  Oops% = 0 if no error; MS-DOS error codes apply if oops% <> 0.
  711.  
  712.     Example:
  713.          sub$ = "C:\123"
  714.          CALL KillSUB(sub$, oops%)
  715.  
  716.  
  717.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  718.  
  719.     Subroutine: MakeSUB(sub$, oops)
  720.     object file: killfile.obj ($asciiz.obj)
  721.  
  722.       Creates a new subdirectory.  Oops% is an MS-DOS error code returned
  723.     by MakeSUB.  If oops% = 0 then no error was detected.
  724.  
  725.     Example:
  726.       sub$ = "\qb4\qlib"     ' make a new subdirectory for QLIB
  727.       CALL MakeSUB(sub$, oops%)
  728.  
  729.  
  730.  
  731.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  732.  
  733.     Subroutine: Rename(old$, new$, oops)
  734.     object file: rename.obj ($asciiz.obj)
  735.  
  736.          Changes filename old$ to new$, returning an MS-DOS error code.
  737.     Similar to BASIC's NAME function, but does not require ON ERROR
  738.     to trap errors.  You may use Rename to move a file from one directory
  739.     to another on the same disk.
  740.  
  741.     Example:
  742.          old$ = "demo.bas"
  743.          new$ = "demo.bak"
  744.          CALL Rename(old$, new$, oops)
  745.  
  746.  
  747.  
  748.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  749.  
  750.     Subroutine: SetDRIVE(d$)
  751.     object file: setdrive.obj
  752.  
  753.          Sets d$ as the default drive.  D$ may be any valid disk drive or
  754.     other logical device (such as a RAMdisk).  SetDRIVE also updates the
  755.     DOSError flag if an invalid drive is specified.
  756.  
  757.     Example:
  758.          d$ = "a:"           ' the drive specifier d$ may be upper or lower
  759.                              ' case and need not include the colon.
  760.          CALL SetDRIVE(d$)   ' drive A: is now the default drive
  761.  
  762.  
  763.  
  764.  
  765.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  766.  
  767.     Subroutine: SetFileAttr(file$, attr%, oops%)
  768.     object file: fileattr.obj ($asciiz.obj)
  769.  
  770.          Changes the file attribute of file$.  File attributes are
  771.     described on the first page of this file.  Oops% returned by this
  772.     subroutine is an MS-DOS error code (see first page of this file).
  773.     If all O.K. then oops% = -1.
  774.  
  775.     Example:  I want to make my QLIB.LIB file read-only
  776.  
  777.          REM  I start by getting the present attribute
  778.          file$ = "QLIB.LIB"
  779.          CALL GetFileAttr(file$, attr%, oops%)
  780.          IF oops% <> -1 THEN
  781.                 REM  Uh oh, something went wrong
  782.                   .
  783.                   .
  784.                   .
  785.          END IF
  786.  
  787.          REM  now I'll add the Read-only bit to the attribute
  788.          attr% = attr% OR 1
  789.          CALL SetFileAttr(file$, attr%, oops%)
  790.  
  791.  
  792.  
  793.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  794.  
  795.      Subroutine: SetFileDate(file$, month%, day%, year%, hour%, min%, sec%)
  796.      object file: setfdate.obj ($asciiz.obj)
  797.  
  798.           Sets file time/date stamp.  The year may be either a four digit
  799.      or two digit number  (e.g., either 1986 or just 86).  DOS will round
  800.      the seconds value off to the next lower even number.  If there is a
  801.      problem with the  filename, or if the file is read-only, the month will
  802.      be returned as -1.  Note that midnight is 24:00.  If hour%, minute% and
  803.      second% are all 0, then the file's time will not be displayed in a
  804.      directory list.
  805.  
  806.      Example:
  807.           file$ = "anyfile.dat"
  808.           CALL SetFileDate(file$, month%, day%, year%, hour%, min%, sec%)
  809.  
  810.  
  811.  
  812.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  813.  
  814.     Subroutine: SetSUB(sub$, oops%)
  815.     object file: killfile.obj ($asciiz.obj)
  816.  
  817.          Changes the default subdirectory to sub$.  Oops% is an error
  818.     code returned to BASIC.
  819.  
  820.     SetSUB's error codes:
  821.  
  822.          oops% = 0         no error
  823.                  1         subdirectory name is a nul string
  824.                  3         path not found
  825.  
  826.     Example:
  827.          directory$ = "\qb4\lib"
  828.          CALL SetSUB(directory$, oops%)
  829.  
  830.  
  831.