Last month, I walked you through the features of the FileSystemObject object—the root object of the File System Object (FSO) model—to help you understand the FSO hierarchy and the role of each available object. This month, I examine in detail the methods and properties of the Drive object.
The Drive Object's Methods and Properties
The Drive object provides information about drives connected to a system. Although the Drive object might seem simple, the Drive object has a lot to offer. As Table 1 shows, you can use the Drive object's properties to return such information as a drive's type of file system, free space, and volume name. However, the Drive object doesn't return information about a drive's content. To retrieve information about the files and folders on a drive, you must use the Folder object, which I'll cover next month.
To work with any of the Drive object's properties, you need to reference the Drive object through the FSO root object. You must use the CreateObject function to instantiate (i.e., create an instance of) the FileSystemObject object and assign that instance to a variable. You can then reference the Drive object with the FileSystemObject object's GetDrive method or Drives property.
When you use the GetDrive method to reference the Drive object, you specify the drive letter as the argument to GetDrive. For example, to access the Drive object representing the A drive, you use the code
Set fso = CreateObject_ ("Scripting.FileSystemObject") Set drv = fso.GetDrive("a")
Unlike GetDrive, you can't simply specify the drive letter when you use the Drives property to reference the Drive object. The Drives property returns the Drives collection, which contains all the drives on the local machine. To access a specific drive in this collection, you need to call the Drives collection's Item property. This property returns the item that its argument specifies. For example, to access the Drive object representing the A drive, you use the code
Set fso = CreateObject_ ("Scripting.FileSystemObject") Set drv = fso.Drives.Item("a")
In both cases, if you specify an invalid drive letter, you receive a system error. Therefore, if you're unsure about the drive letter, you're better off prefacing the code with the On Error Resume Next statement, as the code in Listing 1 shows. Scriptwriters refer to this process as wrapping the code with an error handler. The On Error Goto 0 command in Listing 1 resets the error handler. In other words, the On Error Goto 0 command undoes the On Error Resume Next command, which means that errors are again fatal. (For more information about error-handling statements, see my September 1999 column.)
After you reference the Drive object, you can use any of the object's properties. Let's look at some of the properties you can use to determine a drive's type, file system, size, and identification.
Properties to Determine a Drive's Type and File System
Not all drives are of the same type. For example, you can have a removable drive (i.e., a drive for 3.5" disks), fixed drive, or CD-ROM drive. You use the DriveType property to determine a drive's type. Table 2 shows the drive types and their values.
You can divide the types of drives into two groups: drives that are always ready (e.g., fixed drives) and drives whose status you have to check before accessing (e.g., removable and CD-ROM drives). The IsReady property lets you know about the readiness of those drives that you must check before accessing.
Not all drives have the same file system. The FileSystem property returns a string containing the type of file system. For removable and CD-ROM drives, FileSystem returns the strings FAT and CDFS, respectively. (CDFS stands for CD-ROM File System.) For hard disks in a Windows 2000 (Win2K) or Windows NT system, FileSystem can return FAT, FAT32, or NTFS. For hard disks in a Windows 9x (Win9x) system, FileSystem can return FAT or FAT32.
FAT is the standard file system for Windows. FAT32 is an improved version of FAT that Microsoft mainly introduced to support disk partitions larger than 2GB. Win9x has no problem working with FAT or FAT32 file systems on the same machine. NT can't read FAT32, but Win2K can. NTFS, which is available only on Win2K and NT, is a much more powerful file system that enables interesting features in FSO and other applications. I'll talk more about NTFS when I discuss the Folder object next month.
Properties to Determine a Drive's Size
Three of the Drive object's properties deal with a drive's size: TotalSize, AvailableSpace, and FreeSpace. The TotalSize property tells you the specified drive's total size in bytes. The AvailableSpace property calculates the drive space available to a user. The FreeSpace property calculates the drive's unused (i.e., free) space.
In NT 4.0 and Win9x, AvailableSpace and FreeSpace return the same value—namely, how many bytes are unused on the drive and available to the current user. In Win2K, AvailableSpace and FreeSpace don't always return the same value because the space available to a user and the free space on a drive aren't always identical measurements.
In Win2K, you can enable disk quotas, an exclusive feature of NTFS 5.0 drives. A disk quota is a portion of an NTFS volume that you reserve to a user. The disk quota must be less than the drive's total size. The sum of the disk quotas matches the drive's total size.
If you don't assign disk quotas, AvailableSpace and FreeSpace return the same value. If you assign disk quotas, AvailableSpace and FreeSpace return different values. AvailableSpace's value is the quota minus the disk space occupied. FreeSpace's value is the total number of free bytes on the disk. In other words, FreeSpace returns the difference between the drive's total size and the portion of it that all the users occupy.
When you use the AvailableSpace, FreeSpace, and TotalSize properties, the Drive object calls a Win32 function to perform the calculations. However, this function has a bug if you're using Win9x. The Win32 function truncates the amount of free space to 2GB. For example, suppose the D drive is 10GB, 6.5GB of which is available. If you run the code
Set fso = CreateObject_ ("Scripting.FileSystemObject") Set d = fso.GetDrive("d") MsgBox "Used " _ & d.AvailableSpace _ & " of " & d.TotalSize _ & " bytes"
the MsgBox function displays the result
Used 2147483647 of 2147483647 bytes
In other words, the result incorrectly specifies that you used about 2GB of 2GB.
According to the Microsoft article "BUG: Drive Object Properties Are Incorrect on Large Drives (>2GB)" (http://support.microsoft.com/ support/kb/articles/q225/0/32.asp), Microsoft added a new Windows API function, GetDiskFreeSpaceEx, in Win95's OEM Service Release (OSR) 2 and in Win98 to fix the problem. However, even when I used the GetDiskFreeSpaceEx function, the Drive properties dealing with drive space still failed in Win9x. Fortunately, the Drive object works great in Win2K and NT.
Properties to Determine a Drive's Identification
The DriveLetter, Path, SerialNumber, and VolumeName properties return values that contribute to the identification of a drive. The DriveLetter property returns the letter identifying the drive. You receive just one character—an uppercase letter—with no accompanying colon or backslash. If you want a colon returned with the drive letter, you can use the Path property. This property returns the path name (i.e., an uppercase letter followed by a colon but no backslash). As you can see, the FSO model provides different methods and properties that achieve similar results.
Each drive has a unique identifier called a serial number, a 32-bit value that you can retrieve with the SerialNumber property. The serial number applies to a volume, not to a drive. For 3.5" disks and CD-ROMs, the serial number is an identifier for the disk. Each time you format a 3.5" disk, the serial number changes. In theory, you can use the SerialNumber property with any type of drive, including network drives. In practice, though, the SerialNumber property doesn't return the serial number of a network drive in Win9x—not because of a limitation or bug, but because of a feature in the Win9x OS.
You typically see the serial number in its hexadecimal form when you issue a Dir command from a command-line prompt. No other user interface (UI) in Windows Explorer shows the same information. Thus, the SerialNumber property is useful for tasks such as making sure that a certain program you distribute with a CD-ROM is running from the original CD-ROM and not from a copy. SerialNumber returns the value in decimal form, but you can use the Hex function to convert it to hex form with code such as
Set fso = CreateObject_ ("Scripting.FileSystemObject") Set drv = fso.Drives.Item("f") MsgBox "CD Serial Number is " _ & Hex(drv.SerialNumber)
Another piece of information that contributes to the identification of a drive is the volume label. The VolumeName property renders this label. VolumeName is the only read-write property that the Drive object exposes. To set a drive's volume label, you use the assignment (=) operator to assign a string (i.e., the volume label) to the VolumeName property. FSO does the rest.
Setting the VolumeName property requires writing on the drive. Thus, if the drive is read-only (e.g., a protected CD-ROM), you'll receive the error message Permission denied. This error message is helpful because it specifies the problem.
When you work with VolumeName, you might encounter another error message. If you assign a string longer than 11 characters with code such as
Set fso = CreateObject_ ("Scripting.FileSystemObject") Set drv = fso.Drives.Item("c") drv.VolumeName = _ "Here is my Volume Name"
you'll receive the error message Unknown runtime error. This cryptic error message doesn't hint at what the problem might be. Even worse, the FSO documentation fails to mention the 11-character limit for the volume label.
Putting It All Together
The script in Listing 2 shows how you can use the various properties together to display information about the available drives in a network. After you instantiate the FileSystemObject object and set the s variable to an empty string, you use a For Each...Next statement to loop through all the drives in the Drives collection. For each drive, you use the DriveLetter, FileSystem, and SerialNumber properties to obtain the drive letter, file system, and serial number, respectively. You use the Hex function to convert the serial number into a hex value. You use the concatenation (&) operator with the VBScript constants vbTab (inserts a tab) and vbCrLf (inserts a line return) to display the results in a tabular format, as Screen 1 shows.
A Useful Tool
The objects in the FSO model let you gather useful information about your system. With FSO's Drive object, you can gather important information about your systems' drives, such as the drives' size and type.