Reading CDrive data


The Kind, Number, and Root Property Get procedures can return pre-calculated data:

Public Property Get Kind() As EDriveType
Kind = edtType
End Property

Public Property Get Number() As Integer
Number = Asc(sRoot) - Asc(“A”) + 1
‘ Network drives are zero
If Number > 26 Then Number = 0
End Property

Public Property Get Root() As Variant
Root = sRoot
End Property

The remaining properties can change dynamically, and shouldn’t be pre-calculated. Instead, the calculations are done in the Property Get procedures:

Public Property Get FreeBytes() As Double
‘ Always refresh size since free bytes might change
GetSize
If Not fDriveMissing Then
FreeBytes = CDbl(iFreeClusters) * iSectors * iBytes
End If
End Property

Public Property Get TotalBytes() As Double
‘ Get size info only on first access
If iTotalClusters = 0 And Not fDriveMissing Then GetSize
If Not fDriveMissing Then
TotalBytes = CDbl(iTotalClusters) * iSectors * iBytes
End If
End Property

Public Property Get Label() As String
If Not fDriveMissing Then Label = sLabel
End Property

Public Property Get Serial() As String
If Not fDriveMissing Then Serial = MUtility.FmtHex(iSerial, 8)
End Property

Public Property Get KindStr() As String
KindStr = Choose(edtType + 1, “Unknown”, “Invalid”, “Floppy”, _
“Fixed”, “Network”, “CD-ROM”, “RAM”)
If fDriveMissing Then KindStr = KindStr & “ Missing”
End Property

The FreeBytes and TotalBytes property procedures depend on GetSize, which calls the Win32 GetDiskFreeSpace Function and sets the fDriveMissing flag:

Private Sub GetSize()
Call GetDiskFreeSpace(sRoot, iSectors, iBytes, _
iFreeClusters, iTotalClusters)
fDriveMissing = (Err.LastDllError = 15)
End Sub

Notice that TotalBytes and FreeBytes return Double rather than Long (as I originally coded them). When I wrote the original CDrive for the first edition of this book, disks larger than 2 gigabytes didn’t exist and I didn’t encounter one until I tested CDrive with a network server. Now 2 gigabyte drives are common.


The Label, Serial, and KindStr property procedures call GetLabelSerial to retrieve the appropriate disk information and to determine whether the disk is present. GetLabelSerial is a wrapper for the GetVolumeInformation API function:

Private Sub GetLabelSerial()
sLabel = String$(cMaxPath, 0)
Dim afFlags As Long, iMaxComp As Long
Call GetVolumeInformation(sRoot, sLabel, cMaxPath, iSerial, _
iMaxComp, afFlags, sNullStr, 0)
If Err.LastDllError = 21 Then ‘ The device is not ready
fDriveMissing = True
Else
fDriveMissing = False
sLabel = MUtility.StrZToStr(sLabel)
End If
End Sub

TotalBytes, FreeBytes, Serial, Kind, and KindStr have no Property Let statements because you can’t directly change the size or type of a disk. To make a property read-only, you define the Property Get procedure but not the Property Let. You can change the Label, and CDrive provides a Property Let to do so:

Public Property Let Label(sLabelA As String)
If SetVolumeLabel(sRoot, sLabelA) Then sLabel = sLabelA
End Property