Prerequisites |
Disk partitions < 2 gig. |
|
The
routine presented here to determine a drive's available disk space will return incorrect results on volumes over 2 gigabytes, as supported by
the FAT32 partitions implemented in Windows95 OEM Service Pack 2, Windows 98 (without FAT32 conversion) and NT4. See the comments section
following the code for additional information. |
|
BAS
Module Code |
|
Place the following API declare code into the general
declarations area of a bas module. If this is a one-form project, the declares below could be placed into the
general declaration section of the form instead, with all Public references changed to Private. |
|
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
' applications, but you may not reproduce
' or publish this code on any web site,
' online service, or distribute as source
' on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Type VBNET_DRIVE_INFO
DrvSectors As Long
DrvBytesPerSector As Long
DrvFreeClusters As Long
DrvTotalClusters As Long
DrvSpaceFree As Long
DrvSpaceUsed As Long
DrvSpaceTotal As Long
End Type
Public Declare Function GetDiskFreeSpace Lib "kernel32" _
Alias "GetDiskFreeSpaceA" _
(ByVal lpRootPathName As String, _
lpSectorsPerCluster As Long, _
lpBytesPerSector As Long, _
lpNumberOfFreeClusters As Long, _
lpTotalNumberOfClusters As Long) As Long
Public Declare Function GetLogicalDriveStrings Lib "kernel32" _
Alias "GetLogicalDriveStringsA" _
(ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
|
|
Form
Code |
|
To a project form add 2 command buttons (Command1 and
Command2), and a combo box (Combo1) as indicated in the illustration. Add the following to the form: |
|
Option Explicit
Private Sub Form_Load()
Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
LoadAvailableDrives Combo1
Combo1.ListIndex = 1
End Sub
Private Sub Command2_Click()
Unload Me
End Sub
Private Sub Command1_Click()
'Calls other functions to provide the info.
'Data is stored in my own user-defined type.
Dim VDI As VBNET_DRIVE_INFO
Dim r As Long
Dim RootPathName As String
'get the drive to find
RootPathName = Combo1.List(Combo1.ListIndex)
'get the drive's disk parameters
Call rgbGetDiskFreeSpaceRDI(RootPathName, VDI)
'show the results
Cls
Print
Print " Drive Statistics for ", ": "; UCase$(RootPathName$)
Print
Print " No of Sectors", ": "; VDI.DrvSectors
Print " Bytes per sector", ": "; VDI.DrvBytesPerSector
Print " Clusters Free", ": "; VDI.DrvFreeClusters
Print " Total Clusters", ": "; VDI.DrvTotalClusters
Print " Drive Space Used", ": "; Format$(VDI.DrvSpaceUsed, "###,###,###,##0") & " bytes"
Print " Drive Space Free", ": "; Format$(VDI.DrvSpaceFree, "###,###,###,##0") & " bytes"
Print " Total Drive Size", ": "; Format$(VDI.DrvSpaceTotal, "###,###,###,##0") & " bytes"
End Sub
Private Sub LoadAvailableDrives(cmbo As ComboBox)
Dim lpBuffer As String
'get list of available drives
lpBuffer = GetDriveString()
'Separate the drive strings
'and add to the combo. StripNulls
'will continually shorten the
'string. Loop until a single
'remaining terminating null is
'encountered.
Do Until lpBuffer = Chr(0)
'strip off one drive item
'and add to the combo
cmbo.AddItem StripNulls(lpBuffer)
Loop
End Sub
Private Function GetDriveString() As String
'returns string of available
'drives each separated by a null
Dim sBuffer As String
'possible 26 drives, three characters each, plus trailing null
sBuffer = Space$(26 * 4)
If GetLogicalDriveStrings(Len(sBuffer), sBuffer) Then
'do not trim off trailing null!
GetDriveString = Trim$(sBuffer)
End If
End Function
Private Function StripNulls(startstr As String) As String
'Take a string separated by chr$(0)
'and split off 1 item, shortening the
'string so next item is ready for removal.
Dim pos As Long
pos = InStr(startstr$, Chr$(0))
If pos Then
StripNulls = Mid$(startstr, 1, pos - 1)
startstr = Mid$(startstr, pos + 1, Len(startstr))
Exit Function
End If
End Function
Private Function rgbGetDiskFreeSpaceRDI(RootPathName, _
VDI As VBNET_DRIVE_INFO) As Long
'returns data about the selected drive.
'Passed is the RootPathName; the other
'variables are filled in here.
Dim r As Long
r = GetDiskFreeSpace(RootPathName, VDI.DrvSectors, _
VDI.DrvBytesPerSector, _
VDI.DrvFreeClusters, _
VDI.DrvTotalClusters)
VDI.DrvSpaceTotal = (VDI.DrvSectors * VDI.DrvBytesPerSector * VDI.DrvTotalClusters)
VDI.DrvSpaceFree = (VDI.DrvSectors * VDI.DrvBytesPerSector * VDI.DrvFreeClusters)
VDI.DrvSpaceUsed = VDI.DrvSpaceTotal - VDI.DrvSpaceFree
rgbGetDiskFreeSpaceRDI = r
End Function
|
|
Comments |
With the introduction of Windows95 OEM Service Pack 2 and
Windows 98 with the Fat32 drive system, the GetDiskFreeSpace API can no longer be reliably used on all systems. This raises considerations
for application developers where the application is destined for an unknown build of Win95.
The OEM Service Pack 2 version of Windows95, and Windows 98, provides
among other enhancements, optional support for large drive FAT32 partitions with a cluster size of only 4k. The original release version of
Windows95 supports only partitions or drives up to 2 gigabytes in size. Using the GetDiskFreeSpace code above on drives partitioned and
formatted as FAT32 will return incorrect values when these partitions exceed 2 gigabytes. On these partitions/drives, the correct API to use
is GetDiskFreeSpaceEx.
As an example, the illustration above shows my Drive C total space at 2.147 gig, the free space at 1.948 gig, and the used space at 198 meg.
At the time that graphic was made, I was running the OEM Service Pack 2 version of Win95 with the FAT32 partitions (allowing single
partitions on both of my 2.5 and 3.2 gig drives). The actual statistics for my C drive is 2.54 gig total space, with free space of 1.942 gig
and used space of 538 meg. The illustration above shows different values because the GetDiskFreeSpace API was unable to correctly calculate
the disk size. On a traditional FAT16 drive, the code method above would return the correct statistics.
To assure that the correct method is used to calculate the free space, Microsoft recommends obtaining the user's version of Windows using
GetVersionEx prior to calling the free space API. |
|