home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / qb / toolbox / disk1 / doscalls.bas < prev    next >
Encoding:
BASIC Source File  |  1988-04-27  |  38.2 KB  |  1,043 lines

  1.   ' ************************************************
  2.   ' **  Name:          DOSCALLS                   **
  3.   ' **  Type:          Toolbox                    **
  4.   ' **  Module:        DOSCALLS.BAS               **
  5.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  6.   ' ************************************************
  7.   '
  8.   ' Demonstrates several interrupt calls to MS-DOS.
  9.   '
  10.   ' USAGE:          No command line parameters
  11.   ' REQUIREMENTS:   MS-DOS 3.0 or later
  12.   '                 MIXED.QLB/.LIB
  13.   '.MAK FILE:       (none)
  14.   ' PARAMETERS:     (none)
  15.   ' VARIABLES:      buffer$    String for buffered input demonstration
  16.   '                 x$         Buffered input string
  17.   '                 drive$     Current disk drive name
  18.   '                 desc       Structure of type MediaDescriptorType
  19.   '                 state%     Current status of the Verify state
  20.   '                 oppositeState%   Opposite state for Verify
  21.   '                 disk       Structure of type DiskFreeSpaceType
  22.   '                 country    Structure of type CountryType
  23.   '                 i%         Loop index for creating translation characters
  24.   '                 a$         Characters to be translated
  25.   '                 path$      Current directory
  26.   '                 result%    Result code from call to SetDirectory
  27.   '                 t$         Temporary copy of TIME$
  28.   '                 attr       Structure of type FileAttributesType
  29.   '                 fileName$  Name of file for determining file attributes
  30.   
  31.   
  32.     TYPE RegType
  33.         ax    AS INTEGER
  34.         bx    AS INTEGER
  35.         cx    AS INTEGER
  36.         dx    AS INTEGER
  37.         bp    AS INTEGER
  38.         si    AS INTEGER
  39.         di    AS INTEGER
  40.         flags AS INTEGER
  41.     END TYPE
  42.   
  43.     TYPE RegTypeX
  44.         ax    AS INTEGER
  45.         bx    AS INTEGER
  46.         cx    AS INTEGER
  47.         dx    AS INTEGER
  48.         bp    AS INTEGER
  49.         si    AS INTEGER
  50.         di    AS INTEGER
  51.         flags AS INTEGER
  52.         ds    AS INTEGER
  53.         es    AS INTEGER
  54.     END TYPE
  55.   
  56.     TYPE MediaDescriptorType
  57.         sectorsPerAllocationUnit AS INTEGER
  58.         bytesPerSector AS INTEGER
  59.         FATIdentificationByte AS INTEGER
  60.     END TYPE
  61.   
  62.     TYPE DiskFreeSpaceType
  63.         sectorsPerCluster AS INTEGER
  64.         bytesPerSector AS INTEGER
  65.         clustersPerDrive AS LONG
  66.         availableClusters AS LONG
  67.         availableBytes AS LONG
  68.     END TYPE
  69.   
  70.     TYPE CountryType
  71.         dateTimeFormat AS STRING * 11
  72.         currencySymbol AS STRING * 4
  73.         thousandsSeparator AS STRING * 1
  74.         decimalSeparator AS STRING * 1
  75.         dateSeparator AS STRING * 1
  76.         timeSeparator AS STRING * 1
  77.         currencyThenSymbol AS INTEGER
  78.         currencySymbolSpace AS INTEGER
  79.         currencyPlaces AS INTEGER
  80.         hours24 AS INTEGER
  81.         caseMapSegment AS INTEGER
  82.         caseMapOffset AS INTEGER
  83.         dataListSeparator AS STRING * 1
  84.     END TYPE
  85.   
  86.     TYPE FileAttributesType
  87.         readOnly AS INTEGER
  88.         hidden AS INTEGER
  89.         systemFile AS INTEGER
  90.         archive AS INTEGER
  91.         result AS INTEGER
  92.     END TYPE
  93.   
  94.   ' Subprograms
  95.     DECLARE SUB Interrupt (intnum%, inreg AS RegType, outreg AS RegType)
  96.     DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  97.     DECLARE SUB SetDrive (drive$)
  98.     DECLARE SUB GetMediaDescriptor (drive$, desc AS MediaDescriptorType)
  99.     DECLARE SUB SetVerifyState (state%)
  100.     DECLARE SUB GetDiskFreeSpace (drive$, disk AS DiskFreeSpaceType)
  101.     DECLARE SUB GetCountry (country AS CountryType)
  102.     DECLARE SUB CaseMap (character%, BYVAL Segment%, BYVAL Offset%)
  103.     DECLARE SUB SetDirectory (path$, result%)
  104.     DECLARE SUB WriteToDevice (handle%, a$, result%)
  105.     DECLARE SUB GetFileAttributes (fileName$, attr AS FileAttributesType)
  106.     DECLARE SUB SetFileAttributes (fileName$, attr AS FileAttributesType)
  107.   
  108.   ' Functions
  109.     DECLARE FUNCTION DOSVersion! ()
  110.     DECLARE FUNCTION BufferedKeyInput$ (n%)
  111.     DECLARE FUNCTION GetDrive$ ()
  112.     DECLARE FUNCTION GetVerifyState% ()
  113.     DECLARE FUNCTION TranslateCountry$ (a$, country AS CountryType)
  114.     DECLARE FUNCTION GetDirectory$ (drive$)
  115.   
  116.   ' Try the Buffered Keyboard Input call
  117.     CLS
  118.     PRINT "BufferedKeyInput$:"
  119.     PRINT "Enter a string of up to nine characters...  ";
  120.     x$ = BufferedKeyInput$(9)
  121.     PRINT
  122.     PRINT "Here's the nine-character string result... ";
  123.     PRINT CHR$(34); x$; CHR$(34)
  124.   
  125.   ' Get the MS-DOS version number
  126.     PRINT
  127.     PRINT "DosVersion!:"
  128.     PRINT "DOS Version number is "; DOSVersion!
  129.   
  130.   ' Demonstrate the GetDrive and SetDrive routines
  131.     PRINT
  132.     PRINT "GetDrive$ and SetDrive:"
  133.     drive$ = GetDrive$
  134.     PRINT "The current drive is "; drive$
  135.     PRINT "Setting the current drive to A:"
  136.     SetDrive "A:"
  137.     PRINT "Now the current drive is "; GetDrive$
  138.     PRINT "Setting the current drive back to "; drive$
  139.     SetDrive drive$
  140.     PRINT "Now the current drive is "; GetDrive$
  141.   
  142.   ' Call the MS-DOS "Media Descriptor" function for the current drive
  143.     PRINT
  144.     PRINT "GetMediaDescriptor"
  145.     DIM desc AS MediaDescriptorType
  146.     GetMediaDescriptor drive$, desc
  147.     PRINT "Drive                        "; drive$
  148.     PRINT "Sectors per allocation unit "; desc.sectorsPerAllocationUnit
  149.     PRINT "Bytes per sector            "; desc.bytesPerSector
  150.     PRINT "FAT identification byte      &H"; HEX$(desc.FATIdentificationByte)
  151.   
  152.   ' Wait for user
  153.     PRINT
  154.     PRINT
  155.     PRINT "Press any key to continue"
  156.     DO
  157.     LOOP UNTIL INKEY$ <> ""
  158.     CLS
  159.   
  160.   ' Demonstrate the GetVerifyState and SetVerifyState routines
  161.     PRINT
  162.     PRINT "GetVerifyState% and SetVerifyState:"
  163.     state% = GetVerifyState%
  164.     PRINT "Current verify state is"; state%
  165.     oppositeState% = 1 AND NOT state%
  166.     SetVerifyState oppositeState%
  167.     PRINT "Now the verify state is"; GetVerifyState%
  168.     SetVerifyState state%
  169.     PRINT "Now the verify state is"; GetVerifyState%
  170.   
  171.   ' Determine free space on the current drive
  172.     PRINT
  173.     PRINT "GetDiskFreeSpace:"
  174.     DIM disk AS DiskFreeSpaceType
  175.     GetDiskFreeSpace drive$, disk
  176.     PRINT "Sectors per cluster     "; disk.sectorsPerCluster
  177.     PRINT "Bytes per sector        "; disk.bytesPerSector
  178.     PRINT "Total clusters on drive "; disk.clustersPerDrive
  179.     PRINT "Available clusters      "; disk.availableClusters
  180.     PRINT "Available bytes         "; disk.availableBytes
  181.   
  182.   ' Wait for user
  183.     PRINT
  184.     PRINT
  185.     PRINT "Press any key to continue"
  186.     DO
  187.     LOOP UNTIL INKEY$ <> ""
  188.     CLS
  189.   
  190.   ' Get country-dependent information
  191.     PRINT
  192.     PRINT "GetCountry:"
  193.     DIM country AS CountryType
  194.     GetCountry country
  195.     PRINT "Date and time format    "; country.dateTimeFormat
  196.     PRINT "Currency symbol         "; country.currencySymbol
  197.     PRINT "Thousands separator     "; country.thousandsSeparator
  198.     PRINT "Decimal separator       "; country.decimalSeparator
  199.     PRINT "Date separator          "; country.dateSeparator
  200.     PRINT "Time separator          "; country.timeSeparator
  201.     PRINT "Currency before symbol "; country.currencyThenSymbol
  202.     PRINT "Currency symbol space  "; country.currencySymbolSpace
  203.     PRINT "Currency decimal places"; country.currencyPlaces
  204.     PRINT "24-hour time           "; country.hours24
  205.     PRINT "Case map segment       "; country.caseMapSegment
  206.     PRINT "Case map offset        "; country.caseMapOffset
  207.     PRINT "Data list separator     "; country.dataListSeparator
  208.   
  209.   ' Let's translate lowercase characters for the current country
  210.     PRINT
  211.     PRINT "TranslateCountry$:"
  212.     FOR i% = 128 TO 175
  213.         a$ = a$ + CHR$(i%)
  214.     NEXT i%
  215.     PRINT "Character codes 128 to 175, before and after translation... "
  216.     PRINT a$
  217.     PRINT TranslateCountry$(a$, country)
  218.   
  219.   ' Wait for user
  220.     PRINT
  221.     PRINT
  222.     PRINT "Press any key to continue"
  223.     DO
  224.     LOOP UNTIL INKEY$ <> ""
  225.     CLS
  226.   
  227.   ' Demonstrate the SetDirectory and GetDirectory routines
  228.     PRINT
  229.     PRINT "GetDirectory$ and SetDirectory:"
  230.     path$ = GetDirectory$(drive$)
  231.     PRINT "Current directory is "; path$
  232.     SetDirectory GetDrive$ + "\", result%
  233.     PRINT "Now the directory is "; GetDirectory$(drive$)
  234.     SetDirectory path$, result%
  235.     PRINT "Now the directory is "; GetDirectory$(drive$)
  236.   
  237.   ' Write to a file or device
  238.     PRINT
  239.     PRINT "WriteToDevice:"
  240.     PRINT "Writing a 'bell' character to the CRT"
  241.     WriteToDevice 1, CHR$(7), result%
  242.     t$ = TIME$
  243.     DO
  244.     LOOP UNTIL t$ <> TIME$
  245.     PRINT "Writing a 'bell' character to the printer"
  246.     WriteToDevice 4, CHR$(7), result%
  247.   
  248.   ' Wait for user
  249.     PRINT
  250.     PRINT
  251.     PRINT "Press any key to continue"
  252.     DO
  253.     LOOP UNTIL INKEY$ <> ""
  254.     CLS
  255.   
  256.   ' Demonstrate the GetFileAttributes and SetFileAttributes routines
  257.     PRINT
  258.     PRINT "GetFileAttributes and SetFileAttributes:"
  259.     DIM attr AS FileAttributesType
  260.     fileName$ = "C:\IBMDOS.COM"
  261.     GetFileAttributes fileName$, attr
  262.     PRINT "File attributes for "; fileName$
  263.     PRINT "Result of call "; attr.result
  264.     PRINT "Read only      "; attr.readOnly
  265.     PRINT "Hidden         "; attr.hidden
  266.     PRINT "System         "; attr.systemFile
  267.     PRINT "Archive        "; attr.archive
  268.     PRINT
  269.     attr.hidden = 0
  270.     SetFileAttributes fileName$, attr
  271.     GetFileAttributes fileName$, attr
  272.     PRINT "File attributes for "; fileName$
  273.     PRINT "Result of call "; attr.result
  274.     PRINT "Read only      "; attr.readOnly
  275.     PRINT "Hidden         "; attr.hidden
  276.     PRINT "System         "; attr.systemFile
  277.     PRINT "Archive        "; attr.archive
  278.     PRINT
  279.     attr.hidden = 1
  280.     SetFileAttributes fileName$, attr
  281.     GetFileAttributes fileName$, attr
  282.     PRINT "File attributes for "; fileName$
  283.     PRINT "Result of call "; attr.result
  284.     PRINT "Read only      "; attr.readOnly
  285.     PRINT "Hidden         "; attr.hidden
  286.     PRINT "System         "; attr.systemFile
  287.     PRINT "Archive        "; attr.archive
  288.     PRINT
  289.   
  290.  
  291.   ' ************************************************
  292.   ' **  Name:          BufferedKeyInput$          **
  293.   ' **  Type:          Function                   **
  294.   ' **  Module:        DOSCALLS.BAS               **
  295.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  296.   ' ************************************************
  297.   '
  298.   ' Calls the "Buffered Keyboard Input" MS-DOS function
  299.   ' and returns the entered string of characters.
  300.   '
  301.   ' EXAMPLE OF USE:  x$ = BufferedKeyInput$(n%)
  302.   ' PARAMETERS:      buffer$    Buffer for keyboard input
  303.   ' VARIABLES:       regX       Structure of type RegTypeX
  304.   '                  bufSize%   Length of buffer$
  305.   '                  b$         Working copy of buffer$
  306.   '                  count%     Count of characters entered
  307.   ' MODULE LEVEL
  308.   '   DECLARATIONS:  TYPE RegTypeX
  309.   '                     ax    AS INTEGER
  310.   '                     bx    AS INTEGER
  311.   '                     cx    AS INTEGER
  312.   '                     dx    AS INTEGER
  313.   '                     bp    AS INTEGER
  314.   '                     si    AS INTEGER
  315.   '                     di    AS INTEGER
  316.   '                     flags AS INTEGER
  317.   '                     ds    AS INTEGER
  318.   '                     es    AS INTEGER
  319.   '                  END TYPE
  320.   '
  321.   '   DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  322.   '   DECLARE FUNCTION BufferedKeyInput$ (n%)
  323.   '
  324.     FUNCTION BufferedKeyInput$ (n%) STATIC
  325.         DIM regX AS RegTypeX
  326.         b$ = CHR$(n% + 1) + SPACE$(n% + 1)
  327.         regX.ax = &HA00
  328.         regX.ds = VARSEG(b$)
  329.         regX.dx = SADD(b$)
  330.         InterruptX &H21, regX, regX
  331.         count% = ASC(MID$(b$, 2, 1))
  332.         BufferedKeyInput$ = MID$(b$, 3, count%) + SPACE$(n% - count%)
  333.     END FUNCTION
  334.  
  335.   ' ************************************************
  336.   ' **  Name:          DOSVersion!                **
  337.   ' **  Type:          Function                   **
  338.   ' **  Module:        DOSCALLS.BAS               **
  339.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  340.   ' ************************************************
  341.   '
  342.   ' Returns the version number of MS-DOS.
  343.   '
  344.   ' EXAMPLE OF USE:  PRINT "MS-DOS Version number is "; DOSVersion!
  345.   ' PARAMETERS:      (none)
  346.   ' VARIABLES:       reg        Structure of type RegType
  347.   '                  major%     Integer part of the MS-DOS version number
  348.   '                  minor%     Fractional part of the MS-DOS version number
  349.   ' MODULE LEVEL
  350.   '   DECLARATIONS:  TYPE RegType
  351.   '                     ax    AS INTEGER
  352.   '                     bx    AS INTEGER
  353.   '                     cx    AS INTEGER
  354.   '                     dx    AS INTEGER
  355.   '                     bp    AS INTEGER
  356.   '                     si    AS INTEGER
  357.   '                     di    AS INTEGER
  358.   '                     flags AS INTEGER
  359.   '                  END TYPE
  360.   '
  361.   '      DECLARE SUB Interrupt (intnum%, inreg AS RegType, outreg AS RegType)
  362.   '      DECLARE FUNCTION DOSVersion! ()
  363.   '
  364.     FUNCTION DOSVersion! STATIC
  365.         DIM reg AS RegType
  366.         reg.ax = &H3000
  367.         Interrupt &H21, reg, reg
  368.         major% = reg.ax MOD 256
  369.         minor% = reg.ax \ 256
  370.         DOSVersion! = major% + minor% / 100!
  371.     END FUNCTION
  372.  
  373.   ' ************************************************
  374.   ' **  Name:          GetCountry                 **
  375.   ' **  Type:          Subprogram                 **
  376.   ' **  Module:        DOSCALLS.BAS               **
  377.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  378.   ' ************************************************
  379.   '
  380.   ' Returns country-dependent information as defined
  381.   ' by MS-DOS.
  382.   '
  383.   ' EXAMPLE OF USE:  GetCountry country
  384.   ' PARAMETERS:      country    Structure of type CountryType
  385.   ' VARIABLES:       regX       Structure of type RegTypeX
  386.   '                  c$         Buffer for data returned from interrupt
  387.   ' MODULE LEVEL
  388.   '   DECLARATIONS:  TYPE RegTypeX
  389.   '                     ax    AS INTEGER
  390.   '                     bx    AS INTEGER
  391.   '                     cx    AS INTEGER
  392.   '                     dx    AS INTEGER
  393.   '                     bp    AS INTEGER
  394.   '                     si    AS INTEGER
  395.   '                     di    AS INTEGER
  396.   '                     flags AS INTEGER
  397.   '                     ds    AS INTEGER
  398.   '                     es    AS INTEGER
  399.   '                  END TYPE
  400.   '
  401.   '                  TYPE CountryType
  402.   '                     DateTimeFormat AS STRING * 11
  403.   '                     CurrencySymbol AS STRING * 4
  404.   '                     ThousandsSeparator AS STRING * 1
  405.   '                     DecimalSeparator AS STRING * 1
  406.   '                     DateSeparator AS STRING * 1
  407.   '                     TimeSeparator AS STRING * 1
  408.   '                     CurrencyThenSymbol AS INTEGER
  409.   '                     CurrencySymbolSpace AS INTEGER
  410.   '                     CurrencyPlaces AS INTEGER
  411.   '                     Hours24 AS INTEGER
  412.   '                     caseMapSegment AS INTEGER
  413.   '                     caseMapOffset AS INTEGER
  414.   '                     DataListSeparator AS STRING * 1
  415.   '                  END TYPE
  416.   '
  417.   '   DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  418.   '   DECLARE SUB GetCountry (country AS CountryType)
  419.   '
  420.     SUB GetCountry (country AS CountryType)
  421.         DIM regX AS RegTypeX
  422.         regX.ax = &H3800
  423.         c$ = SPACE$(32)
  424.         regX.ds = VARSEG(c$)
  425.         regX.dx = SADD(c$)
  426.         InterruptX &H21, regX, regX
  427.         SELECT CASE CVI(LEFT$(c$, 2))
  428.         CASE 0
  429.             country.dateTimeFormat = "h:m:s m/d/y"
  430.         CASE 1
  431.             country.dateTimeFormat = "h:m:s d/m/y"
  432.         CASE 2
  433.             country.dateTimeFormat = "y/m/d h:m:s"
  434.         CASE ELSE
  435.             country.dateTimeFormat = "h:m:s m/d/y"
  436.         END SELECT
  437.         country.currencySymbol = MID$(c$, 3, 4)
  438.         country.thousandsSeparator = MID$(c$, 8, 1)
  439.         country.decimalSeparator = MID$(c$, 10, 1)
  440.         country.dateSeparator = MID$(c$, 12, 1)
  441.         country.timeSeparator = MID$(c$, 14, 1)
  442.         country.currencyThenSymbol = ASC(MID$(c$, 16)) AND 1
  443.         country.currencySymbolSpace = (ASC(MID$(c$, 16)) AND 2) \ 2
  444.         country.currencyPlaces = ASC(MID$(c$, 17))
  445.         country.hours24 = ASC(MID$(c$, 18))
  446.         country.caseMapSegment = CVI(MID$(c$, 21, 2))
  447.         country.caseMapOffset = CVI(MID$(c$, 19, 2))
  448.         country.dataListSeparator = MID$(c$, 23, 1)
  449.     END SUB
  450.  
  451.   ' ************************************************
  452.   ' **  Name:          GetDirectory$              **
  453.   ' **  Type:          Function                   **
  454.   ' **  Module:        DOSCALLS.BAS               **
  455.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  456.   ' ************************************************
  457.   '
  458.   ' Returns the name of the current directory for any drive.
  459.   '
  460.   ' EXAMPLE OF USE:  path$ = GetDirectory$(drive$)
  461.   ' PARAMETERS:      drive$     Drive of concern, or null string for default
  462.   '                             drive
  463.   ' VARIABLES:       regX       Structure of type RegTypeX
  464.   '                  d$         Working copy of drive$
  465.   '                  p$         Buffer space for returned path
  466.   ' MODULE LEVEL
  467.   '   DECLARATIONS:  TYPE RegTypeX
  468.   '                     ax    AS INTEGER
  469.   '                     bx    AS INTEGER
  470.   '                     cx    AS INTEGER
  471.   '                     dx    AS INTEGER
  472.   '                     bp    AS INTEGER
  473.   '                     si    AS INTEGER
  474.   '                     di    AS INTEGER
  475.   '                     flags AS INTEGER
  476.   '                     ds    AS INTEGER
  477.   '                     es    AS INTEGER
  478.   '                  END TYPE
  479.   '
  480.   '   DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  481.   '   DECLARE FUNCTION GetDirectory$ (drive$)
  482.   '
  483.     FUNCTION GetDirectory$ (drive$) STATIC
  484.         DIM regX AS RegTypeX
  485.         IF drive$ = "" THEN
  486.             d$ = GetDrive$
  487.         ELSE
  488.             d$ = UCASE$(drive$)
  489.         END IF
  490.         drive% = ASC(d$) - 64
  491.         regX.dx = drive%
  492.         regX.ax = &H4700
  493.         p$ = SPACE$(64)
  494.         regX.ds = VARSEG(p$)
  495.         regX.si = SADD(p$)
  496.         InterruptX &H21, regX, regX
  497.         p$ = LEFT$(p$, INSTR(p$, CHR$(0)) - 1)
  498.         GetDirectory$ = LEFT$(d$, 1) + ":\" + p$
  499.         IF regX.flags AND 1 THEN
  500.             GetDirectory$ = ""
  501.         END IF
  502.     END FUNCTION
  503.  
  504.   ' ************************************************
  505.   ' **  Name:          GetDiskFreeSpace           **
  506.   ' **  Type:          Subprogram                 **
  507.   ' **  Module:        DOSCALLS.BAS               **
  508.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  509.   ' ************************************************
  510.   '
  511.   ' Get information about a drive's organization, including
  512.   ' total number of bytes available.
  513.   '
  514.   ' EXAMPLE OF USE:  GetDiskFreeSpace drive$, disk
  515.   ' PARAMETERS:      drive$     Disk drive designation
  516.   '                  disk       Structure of type DiskFreeSpaceType
  517.   ' VARIABLES:       reg        Structure of type RegType
  518.   '                  drive%     Numeric drive designation
  519.   ' MODULE LEVEL
  520.   '   DECLARATIONS:  TYPE RegType
  521.   '                     ax    AS INTEGER
  522.   '                     bx    AS INTEGER
  523.   '                     cx    AS INTEGER
  524.   '                     dx    AS INTEGER
  525.   '                     bp    AS INTEGER
  526.   '                     si    AS INTEGER
  527.   '                     di    AS INTEGER
  528.   '                     flags AS INTEGER
  529.   '                  END TYPE
  530.   '
  531.   '                  TYPE DiskFreeSpaceType
  532.   '                     sectorsPerCluster AS INTEGER
  533.   '                     bytesPerSector AS INTEGER
  534.   '                     clustersPerDrive AS LONG
  535.   '                     availableClusters AS LONG
  536.   '                     availableBytes AS LONG
  537.   '                  END TYPE
  538.   '
  539.   '      DECLARE SUB Interrupt (intnum%, inreg AS RegType, outreg AS RegType)
  540.   '      DECLARE SUB GetDiskFreeSpace (drive$, disk AS DiskFreeSpaceType)
  541.   '
  542.     SUB GetDiskFreeSpace (drive$, disk AS DiskFreeSpaceType)
  543.         DIM reg AS RegType
  544.         IF drive$ <> "" THEN
  545.             drive% = ASC(UCASE$(drive$)) - 64
  546.         ELSE
  547.             drive% = 0
  548.         END IF
  549.         IF drive% >= 0 THEN
  550.             reg.dx = drive%
  551.         ELSE
  552.             reg.dx = 0
  553.         END IF
  554.         reg.ax = &H3600
  555.         Interrupt &H21, reg, reg
  556.         disk.sectorsPerCluster = reg.ax
  557.         disk.bytesPerSector = reg.cx
  558.         IF reg.dx >= 0 THEN
  559.             disk.clustersPerDrive = reg.dx
  560.         ELSE
  561.             disk.clustersPerDrive = reg.dx + 65536
  562.         END IF
  563.         IF reg.bx >= 0 THEN
  564.             disk.availableClusters = reg.bx
  565.         ELSE
  566.             disk.availableClusters = reg.bx + 65536
  567.         END IF
  568.         disk.availableBytes = disk.availableClusters * reg.ax * reg.cx
  569.     END SUB
  570.  
  571.   ' ************************************************
  572.   ' **  Name:          GetDrive$                  **
  573.   ' **  Type:          Function                   **
  574.   ' **  Module:        DOSCALLS.BAS               **
  575.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  576.   ' ************************************************
  577.   '
  578.   ' Returns the current disk drive name, such as "A:".
  579.   '
  580.   ' EXAMPLE OF USE:  drive$ = GetDrive$
  581.   ' PARAMETERS:      (none)
  582.   ' VARIABLES:       reg        Structure of type RegType
  583.   ' MODULE LEVEL
  584.   '   DECLARATIONS:  TYPE RegType
  585.   '                     ax    AS INTEGER
  586.   '                     bx    AS INTEGER
  587.   '                     cx    AS INTEGER
  588.   '                     dx    AS INTEGER
  589.   '                     bp    AS INTEGER
  590.   '                     si    AS INTEGER
  591.   '                     di    AS INTEGER
  592.   '                     flags AS INTEGER
  593.   '                  END TYPE
  594.   '
  595.   '      DECLARE SUB Interrupt (intnum%, inreg AS RegType, outreg AS RegType)
  596.   '      DECLARE FUNCTION GetDrive$ ()
  597.   '
  598.     FUNCTION GetDrive$ STATIC
  599.         DIM reg AS RegType
  600.         reg.ax = &H1900
  601.         Interrupt &H21, reg, reg
  602.         GetDrive$ = CHR$((reg.ax AND &HFF) + 65) + ":"
  603.     END FUNCTION
  604.  
  605.   ' ************************************************
  606.   ' **  Name:          GetFileAttributes          **
  607.   ' **  Type:          Subprogram                 **
  608.   ' **  Module:        DOSCALLS.BAS               **
  609.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  610.   ' ************************************************
  611.   '
  612.   ' Returns the file attribute settings for a file.
  613.   '
  614.   ' EXAMPLE OF USE:  GetFileAttributes fileName$, attr
  615.   ' PARAMETERS:      fileName$  Name of file
  616.   '                  attr       Structure of type FileAttributesType
  617.   ' VARIABLES:       regX       Structure of type RegTypeX
  618.   '                  f$         Null terminated copy of fileName$
  619.   ' MODULE LEVEL
  620.   '   DECLARATIONS:  TYPE RegTypeX
  621.   '                     ax    AS INTEGER
  622.   '                     bx    AS INTEGER
  623.   '                     cx    AS INTEGER
  624.   '                     dx    AS INTEGER
  625.   '                     bp    AS INTEGER
  626.   '                     si    AS INTEGER
  627.   '                     di    AS INTEGER
  628.   '                     flags AS INTEGER
  629.   '                     ds    AS INTEGER
  630.   '                     es    AS INTEGER
  631.   '                  END TYPE
  632.   '
  633.   '                  TYPE FileAttributesType
  634.   '                     readOnly AS INTEGER
  635.   '                     hidden AS INTEGER
  636.   '                     systemFile AS INTEGER
  637.   '                     archive AS INTEGER
  638.   '                     result AS INTEGER
  639.   '                  END TYPE
  640.   '
  641.   '   DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  642.   '   DECLARE SUB GetFileAttributes (fileName$, attr AS FileAttributesType)
  643.   '
  644.     SUB GetFileAttributes (fileName$, attr AS FileAttributesType) STATIC
  645.         DIM regX AS RegTypeX
  646.         regX.ax = &H4300
  647.         f$ = fileName$ + CHR$(0)
  648.         regX.ds = VARSEG(f$)
  649.         regX.dx = SADD(f$)
  650.         InterruptX &H21, regX, regX
  651.         IF regX.flags AND 1 THEN
  652.             attr.result = regX.ax
  653.         ELSE
  654.             attr.result = 0
  655.         END IF
  656.         attr.readOnly = regX.cx AND 1
  657.         attr.hidden = (regX.cx \ 2) AND 1
  658.         attr.systemFile = (regX.cx \ 4) AND 1
  659.         attr.archive = (regX.cx \ 32) AND 1
  660.     END SUB
  661.  
  662.   ' ************************************************
  663.   ' **  Name:          GetMediaDescriptor         **
  664.   ' **  Type:          Subprogram                 **
  665.   ' **  Module:        DOSCALLS.BAS               **
  666.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  667.   ' ************************************************
  668.   '
  669.   ' Calls the MS-DOS "Get Media Descriptor" function for
  670.   ' the indicated drive.  Results are returned in a
  671.   ' structure of type MediaDescriptorType.
  672.   '
  673.   ' EXAMPLE OF USE:  GetMediaDescriptor drive$, desc
  674.   ' PARAMETERS:      drive$     Drive designation, such as "A:"
  675.   '                  desc       Structure of type MediaDescriptorType
  676.   ' VARIABLES:       regX       Structure of type RegTypeX
  677.   '                  drive%     Numeric drive designation
  678.   ' MODULE LEVEL
  679.   '   DECLARATIONS:  TYPE RegTypeX
  680.   '                     ax    AS INTEGER
  681.   '                     bx    AS INTEGER
  682.   '                     cx    AS INTEGER
  683.   '                     dx    AS INTEGER
  684.   '                     bp    AS INTEGER
  685.   '                     si    AS INTEGER
  686.   '                     di    AS INTEGER
  687.   '                     flags AS INTEGER
  688.   '                     ds    AS INTEGER
  689.   '                     es    AS INTEGER
  690.   '                  END TYPE
  691.   '
  692.   '                  TYPE MediaDescriptorType
  693.   '                     sectorsPerAllocationUnit AS INTEGER
  694.   '                     bytesPerSector AS INTEGER
  695.   '                     FATIdentificationByte AS INTEGER
  696.   '                  END TYPE
  697.   '
  698.   '   DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  699.   '   DECLARE SUB GetMediaDescriptor (drive$, desc AS MediaDescriptorType)
  700.   '
  701.     SUB GetMediaDescriptor (drive$, desc AS MediaDescriptorType) STATIC
  702.         DIM regX AS RegTypeX
  703.         IF drive$ <> "" THEN
  704.             drive% = ASC(UCASE$(drive$)) - 64
  705.         ELSE
  706.             drive% = 0
  707.         END IF
  708.         IF drive% >= 0 THEN
  709.             regX.dx = drive%
  710.         ELSE
  711.             regX.dx = 0
  712.         END IF
  713.         regX.ax = &H1C00
  714.         InterruptX &H21, regX, regX
  715.         desc.sectorsPerAllocationUnit = regX.ax AND &HFF
  716.         desc.bytesPerSector = regX.cx
  717.         DEF SEG = regX.ds
  718.         desc.FATIdentificationByte = PEEK(regX.bx)
  719.         DEF SEG
  720.     END SUB
  721.  
  722.   ' ************************************************
  723.   ' **  Name:          GetVerifyState%            **
  724.   ' **  Type:          Function                   **
  725.   ' **  Module:        DOSCALLS.BAS               **
  726.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  727.   ' ************************************************
  728.   '
  729.   ' Returns the current state of the MS-DOS "Verify After
  730.   ' Write" flag.
  731.   '
  732.   ' EXAMPLE OF USE:  state% = GetVerifyState%
  733.   ' PARAMETERS:      (none)
  734.   ' VARIABLES:       reg        Structure of type RegType
  735.   ' MODULE LEVEL
  736.   '   DECLARATIONS:  TYPE RegTypeX
  737.   '                     ax    AS INTEGER
  738.   '                     bx    AS INTEGER
  739.   '                     cx    AS INTEGER
  740.   '                     dx    AS INTEGER
  741.   '                     bp    AS INTEGER
  742.   '                     si    AS INTEGER
  743.   '                     di    AS INTEGER
  744.   '                     flags AS INTEGER
  745.   '                  END TYPE
  746.   '
  747.   '      DECLARE SUB Interrupt (intnum%, inreg AS RegType, outreg AS RegType)
  748.   '      DECLARE FUNCTION GetVerifyState% ()
  749.   '
  750.     FUNCTION GetVerifyState% STATIC
  751.         DIM reg AS RegType
  752.         reg.ax = &H5400
  753.         Interrupt &H21, reg, reg
  754.         GetVerifyState% = reg.ax AND &HFF
  755.     END FUNCTION
  756.  
  757.   ' ************************************************
  758.   ' **  Name:          SetDirectory               **
  759.   ' **  Type:          Subprogram                 **
  760.   ' **  Module:        DOSCALLS.BAS               **
  761.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  762.   ' ************************************************
  763.   '
  764.   ' Sets the current directory.
  765.   '
  766.   ' EXAMPLE OF USE:  SetDirectory path$, result%
  767.   ' PARAMETERS:      path$      The path to the directory
  768.   '                  result%    Returned error code, zero if successful
  769.   ' VARIABLES:       regX       Structure of type RegTypeX
  770.   '                  p$         Null terminated copy of path$
  771.   ' MODULE LEVEL
  772.   '   DECLARATIONS:  TYPE RegTypeX
  773.   '                     ax    AS INTEGER
  774.   '                     bx    AS INTEGER
  775.   '                     cx    AS INTEGER
  776.   '                     dx    AS INTEGER
  777.   '                     bp    AS INTEGER
  778.   '                     si    AS INTEGER
  779.   '                     di    AS INTEGER
  780.   '                     flags AS INTEGER
  781.   '                     ds    AS INTEGER
  782.   '                     es    AS INTEGER
  783.   '                  END TYPE
  784.   '
  785.   '   DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  786.   '   DECLARE SUB SetDirectory (path$, result%)
  787.   '
  788.     SUB SetDirectory (path$, result%) STATIC
  789.         DIM regX AS RegTypeX
  790.         regX.ax = &H3B00
  791.         p$ = path$ + CHR$(0)
  792.         regX.ds = VARSEG(p$)
  793.         regX.dx = SADD(p$)
  794.         InterruptX &H21, regX, regX
  795.         IF regX.flags AND 1 THEN
  796.             result% = regX.ax
  797.         ELSE
  798.             result% = 0
  799.         END IF
  800.     END SUB
  801.  
  802.   ' ************************************************
  803.   ' **  Name:          SetDrive                   **
  804.   ' **  Type:          Subprogram                 **
  805.   ' **  Module:        DOSCALLS.BAS               **
  806.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  807.   ' ************************************************
  808.   '
  809.   ' Calls MS-DOS to set the current drive.
  810.   '
  811.   ' EXAMPLE OF USE:  SetDrive d$
  812.   ' PARAMETERS:      d$         Drive designation, such as "A:"
  813.   ' VARIABLES:       reg        Structure of type RegType
  814.   '                  drive%     Numeric value of drive
  815.   ' MODULE LEVEL
  816.   '   DECLARATIONS:  TYPE RegTypeX
  817.   '                     ax    AS INTEGER
  818.   '                     bx    AS INTEGER
  819.   '                     cx    AS INTEGER
  820.   '                     dx    AS INTEGER
  821.   '                     bp    AS INTEGER
  822.   '                     si    AS INTEGER
  823.   '                     di    AS INTEGER
  824.   '                     flags AS INTEGER
  825.   '                  END TYPE
  826.   '
  827.   '      DECLARE SUB Interrupt (intnum%, inreg AS RegType, outreg AS RegType)
  828.   '      DECLARE SUB SetDrive (drive$)
  829.   '
  830.     SUB SetDrive (drive$) STATIC
  831.         DIM reg AS RegType
  832.         IF drive$ <> "" THEN
  833.             drive% = ASC(UCASE$(drive$)) - 65
  834.         ELSE
  835.             drive% = 0
  836.         END IF
  837.         IF drive% >= 0 THEN
  838.             reg.dx = drive%
  839.         ELSE
  840.             reg.dx = 0
  841.         END IF
  842.         reg.ax = &HE00
  843.         Interrupt &H21, reg, reg
  844.     END SUB
  845.  
  846.   ' ************************************************
  847.   ' **  Name:          SetFileAttributes          **
  848.   ' **  Type:          Subprogram                 **
  849.   ' **  Module:        DOSCALLS.BAS               **
  850.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  851.   ' ************************************************
  852.   '
  853.   ' Sets attribute bits for a file.
  854.   '
  855.   ' EXAMPLE OF USE:  SetFileAttributes fileName$, attr
  856.   ' PARAMETERS:      fileName$  Name of file
  857.   '                  attr       Structure of type FileAttributesType
  858.   ' VARIABLES:       regX       Structure of type RegTypeX
  859.   '                  f$         Null terminated copy of fileName$
  860.   ' MODULE LEVEL
  861.   '   DECLARATIONS:  TYPE RegTypeX
  862.   '                     ax    AS INTEGER
  863.   '                     bx    AS INTEGER
  864.   '                     cx    AS INTEGER
  865.   '                     dx    AS INTEGER
  866.   '                     bp    AS INTEGER
  867.   '                     si    AS INTEGER
  868.   '                     di    AS INTEGER
  869.   '                     flags AS INTEGER
  870.   '                     ds    AS INTEGER
  871.   '                     es    AS INTEGER
  872.   '                  END TYPE
  873.   '
  874.   '                 TYPE FileAttributesType
  875.   '                    readOnly AS INTEGER
  876.   '                    hidden AS INTEGER
  877.   '                    systemFile AS INTEGER
  878.   '                    archive AS INTEGER
  879.   '                    result AS INTEGER
  880.   '                 END TYPE
  881.   '
  882.   '   DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  883.   '   DECLARE SUB SetFileAttributes (fileName$, attr AS FileAttributesType)
  884.   '
  885.     SUB SetFileAttributes (fileName$, attr AS FileAttributesType)
  886.         DIM regX AS RegTypeX
  887.         regX.ax = &H4301
  888.         IF attr.readOnly THEN
  889.             regX.cx = 1
  890.         ELSE
  891.             regX.cx = 0
  892.         END IF
  893.         IF attr.hidden THEN
  894.             regX.cx = regX.cx + 2
  895.         END IF
  896.         IF attr.systemFile THEN
  897.             regX.cx = regX.cx + 4
  898.         END IF
  899.         IF attr.archive THEN
  900.             regX.cx = regX.cx + 32
  901.         END IF
  902.         f$ = fileName$ + CHR$(0)
  903.         regX.ds = VARSEG(f$)
  904.         regX.dx = SADD(f$)
  905.         InterruptX &H21, regX, regX
  906.         IF regX.flags AND 1 THEN
  907.             attr.result = regX.ax
  908.         ELSE
  909.             attr.result = 0
  910.         END IF
  911.     END SUB
  912.  
  913.   ' ************************************************
  914.   ' **  Name:          SetVerifyState             **
  915.   ' **  Type:          Subprogram                 **
  916.   ' **  Module:        DOSCALLS.BAS               **
  917.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  918.   ' ************************************************
  919.   '
  920.   ' Sets or clears the "Verify After Write" MS-DOS flag.
  921.   '
  922.   ' EXAMPLE OF USE:  SetVerifyState state%
  923.   ' PARAMETERS:      state%     If 0, resets Verify;  If non-zero,
  924.   '                             then sets Verify on
  925.   ' VARIABLES:       reg        Structure of type RegType
  926.   ' MODULE LEVEL
  927.   '   DECLARATIONS:  TYPE RegTypeX
  928.   '                     ax    AS INTEGER
  929.   '                     bx    AS INTEGER
  930.   '                     cx    AS INTEGER
  931.   '                     dx    AS INTEGER
  932.   '                     bp    AS INTEGER
  933.   '                     si    AS INTEGER
  934.   '                     di    AS INTEGER
  935.   '                     flags AS INTEGER
  936.   '                  END TYPE
  937.   '
  938.   '      DECLARE SUB Interrupt (intnum%, inreg AS RegType, outreg AS RegType)
  939.   '      DECLARE SUB SetVerifyState (state%)
  940.   '
  941.     SUB SetVerifyState (state%) STATIC
  942.         DIM reg AS RegType
  943.         IF state% THEN
  944.             reg.ax = &H2E01
  945.         ELSE
  946.             reg.ax = &H2E00
  947.         END IF
  948.         Interrupt &H21, reg, reg
  949.     END SUB
  950.  
  951.   ' ************************************************
  952.   ' **  Name:          TranslateCountry$          **
  953.   ' **  Type:          Function                   **
  954.   ' **  Module:        DOSCALLS.BAS               **
  955.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  956.   ' ************************************************
  957.   '
  958.   ' Returns a string of characters translated according to
  959.   ' the current country setting of MS-DOS.
  960.   '
  961.   ' EXAMPLE OF USE:  b$ = TranslateCountry$(a$, country)
  962.   ' PARAMETERS:      a$         String to be translated
  963.   '                  country    Structure of type CountryType
  964.   ' VARIABLES:       i%         Index to each character of a$
  965.   '                  c%         Byte value of each character in a$
  966.   ' MODULE LEVEL
  967.   '   DECLARATIONS:  TYPE CountryType
  968.   '                     DateTimeFormat AS STRING * 11
  969.   '                     CurrencySymbol AS STRING * 4
  970.   '                     ThousandsSeparator AS STRING * 1
  971.   '                     DecimalSeparator AS STRING * 1
  972.   '                     DateSeparator AS STRING * 1
  973.   '                     TimeSeparator AS STRING * 1
  974.   '                     CurrencyThenSymbol AS INTEGER
  975.   '                     CurrencySymbolSpace AS INTEGER
  976.   '                     CurrencyPlaces AS INTEGER
  977.   '                     Hours24 AS INTEGER
  978.   '                     caseMapSegment AS INTEGER
  979.   '                     caseMapOffset AS INTEGER
  980.   '                     DataListSeparator AS STRING * 1
  981.   '                  END TYPE
  982.   '
  983.   '           DECLARE SUB CaseMap (character%, BYVAL Segment%, BYVAL Offset%)
  984.   '           DECLARE FUNCTION TranslateCountry$ (a$, country AS CountryType)
  985.   '
  986.     FUNCTION TranslateCountry$ (a$, country AS CountryType) STATIC
  987.         FOR i% = 1 TO LEN(a$)
  988.             c% = ASC(MID$(a$, i%))
  989.             CaseMap c%, country.caseMapSegment, country.caseMapOffset
  990.             MID$(a$, i%, 1) = CHR$(c%)
  991.         NEXT i%
  992.         TranslateCountry$ = a$
  993.     END FUNCTION
  994.  
  995.   ' ************************************************
  996.   ' **  Name:          WriteToDevice              **
  997.   ' **  Type:          Subprogram                 **
  998.   ' **  Module:        DOSCALLS.BAS               **
  999.   ' **  Language:      Microsoft QuickBASIC 4.00  **
  1000.   ' ************************************************
  1001.   '
  1002.   ' Writes bytes to a file or device.
  1003.   '
  1004.   ' EXAMPLE OF USE:  WriteToDevice handle%, a$, result%
  1005.   ' PARAMETERS:      handle%    File or device handle
  1006.   '                  a$         String to be output
  1007.   '                  result%    Error code returned from MS-DOS
  1008.   ' VARIABLES:       regX       Structure of type RegTypeX
  1009.   ' MODULE LEVEL
  1010.   '   DECLARATIONS:  TYPE RegTypeX
  1011.   '                     ax    AS INTEGER
  1012.   '                     bx    AS INTEGER
  1013.   '                     cx    AS INTEGER
  1014.   '                     dx    AS INTEGER
  1015.   '                     bp    AS INTEGER
  1016.   '                     si    AS INTEGER
  1017.   '                     di    AS INTEGER
  1018.   '                     flags AS INTEGER
  1019.   '                     ds    AS INTEGER
  1020.   '                     es    AS INTEGER
  1021.   '                  END TYPE
  1022.   '
  1023.   '   DECLARE SUB InterruptX (intnum%, inreg AS RegTypeX, outreg AS RegTypeX)
  1024.   '   DECLARE SUB WriteToDevice (handle%, a$, result%)
  1025.   '
  1026.     SUB WriteToDevice (handle%, a$, result%) STATIC
  1027.         DIM regX AS RegTypeX
  1028.         regX.ax = &H4000
  1029.         regX.cx = LEN(a$)
  1030.         regX.bx = handle%
  1031.         regX.ds = VARSEG(a$)
  1032.         regX.dx = SADD(a$)
  1033.         InterruptX &H21, regX, regX
  1034.         IF regX.flags AND 1 THEN
  1035.             result% = regX.ax
  1036.         ELSEIF regX.ax <> LEN(a$) THEN
  1037.             result% = -1
  1038.         ELSE
  1039.             result% = 0
  1040.         END IF
  1041.     END SUB
  1042.  
  1043.