Previous Book Contents Book Index Next

Inside Macintosh: Files /
Chapter 2 - File Manager / Using the File Manager


Determining the Amount of Free Space on a Volume

You can determine how much space is free on a particular volume by calling the low-level function PBHGetVInfo. This function returns, in the ioVFrBlk field of the parameter block passed to it, the number of free allocation blocks on a volume. It also returns, in the ioVAlBlkSiz field, the number of bytes in the allocation blocks on that volume. By multiplying those two values, you can determine how many bytes are free on a particular volume.

There is, however, one complication in this process. The ioVFrBlk field of the parameter block is actually an unsigned integer and can contain values from 0 to 65,535. However, because Pascal does not support unsigned integers, it interprets the values in the ioVFrBlk field as lying in the range -32,768 to 32,767. (Integers are stored as 16-bit quantities where the high-order bit indicates whether the value is true binary or a negated value in its two's complement positive form.) If, for example, a volume has 40,000 allocation blocks free and your application blindly returned the value in the ioVFrBlk field, it would erroneously report that the volume had -25,536 allocation blocks available.

You can circumvent this problem by forcing Pascal to interpret the high-order bit as
part of the number of free blocks. For example, if you install the value returned in the ioVFrBlk field as the low-order word of a long integer, the high-order bit of that
word is no longer the high-order bit of that long integer and hence is not interpreted
as a sign indication. The data type TwoIntsMakeALong provides a convenient way
to accomplish this.

TYPE
   TwoIntsMakeALong =      {two integers make a long integer}
   RECORD
      CASE Integer OF
         1: (long: LongInt);
         2: (ints: ARRAY[0..1] OF Integer);
   END;
Listing 2-6 illustrates how to use this technique to determine the amount of free space on a volume (specified by its volume reference number).

Listing 2-6 Determining the amount of free space on a volume

FUNCTION GetVolumeFreeSpace (myVol: Integer): LongInt;
VAR
   myHPB:   HParamBlockRec;      {parameter block for PBHGetVInfo}
   myErr:   OSErr;               {result code from PBHGetVInfo}
   myRec:   TwoIntsMakeALong;    {easy way to get an unsigned int}
BEGIN
   WITH myHPB DO
      BEGIN
         ioNamePtr := NIL;
         ioVRefNum := myVol;
         ioVolIndex := 0;
      END;
   myErr := PBHGetVInfo(@myHPB, FALSE);
   IF myErr = noErr THEN
      BEGIN
         myRec.ints[0] := 0;
         myRec.ints[1] := myHPB.ioVFrBlk;
         GetVolumeFreeSpace := myRec.long * myHPB.ioVAlBlkSiz;
      END
   ELSE
      GetVolumeFreeSpace := 0;
END;
If the value passed to GetVolumeFreeSpace is a valid volume reference number,
then this function reads the number of free allocation blocks on the volume, installs
that number as the low-order word of a long integer, and performs the necessary multiplication to determine how many bytes are free on the volume.

Note
You could avoid these complications with unsigned integers by calling PBHGetVInfo as illustrated and then passing the value returned in the ioVDrvInfo field to the high-level function GetVInfo. The technique using the TwoIntsMakeALong data type to convert unsigned integers to long integers is illustrated here because it is useful when reading the fields of many other File Manager data structures from Pascal. For example, the vcbFreeBks field of a volume control block contains an unsigned integer that you can interpret in this way.

Previous Book Contents Book Index Next

© Apple Computer, Inc.
2 JUL 1996