Learn Microsoft Access Advanced Programming Techniques, Tips and Tricks.

Get Disk Free Space Windows API

 Introduction.

Last week, we explored the ShowWindow and PostMessage Windows API functions. Using the built-in .hWnd property of Forms and Reports, we were able to change their window states (Normal, Minimized, Maximized, Hidden, or Closed) without relying on the FindWindow API to fetch their window handles.

This time, we will look at another simple but very useful Windows API function: GetDiskFreeSpace.

This function allows us to check the free space available on any logical drive in the system. Its declaration in VBA is as follows:

#If VBA7 Then

    Declare PtrSafe Function GetDiskFreeSpace Lib "kernel32" _

        Alias "GetDiskFreeSpaceA" ( _

        ByVal lpRootPathName As String, _

        lpSectorsPerCluster As Long, _

        lpBytesPerSector As Long, _

        lpNumberOfFreeClusters As Long, _

        lpTotalNumberOfClusters As Long) As Long

#Else

    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

#End If

GetDiskFreeSpace API Parameters

Declare PtrSafe Function GetDiskFreeSpace Lib "kernel32" _ Alias "GetDiskFreeSpaceA" ( _ ByVal lpRootPathName As String, _ lpSectorsPerCluster As Long, _ lpBytesPerSector As Long, _ lpNumberOfFreeClusters As Long, _ lpTotalNumberOfClusters As Long) As Long

1. lpRootPathName (String)

  • This is the drive name you want to check.

  • It must be a string ending with a backslash.
    Example:

    • "C:\" → checks the C drive

    • "D:\" → checks the D drive

  • If you pass vbNullString, it will use the current drive.


2. lpSectorsPerCluster (Long – Output)

  • The function fills this variable with the number of sectors per cluster on the drive.

  • A cluster is the smallest unit of disk storage allocation.

Example:
If lpSectorsPerCluster = 8 It means each cluster contains 8 sectors.


3. lpBytesPerSector (Long – Output)

  • This returns the number of bytes in each sector.

  • Typically, most drives use 512 bytes per sector, but newer drives may use 4096 bytes per sector.


4. lpNumberOfFreeClusters (Long – Output)

  • Returns the number of free clusters available on the drive.

  • This tells you how many “allocation units” are currently unused.


5. lpTotalNumberOfClusters (Long – Output)

  • Returns the total number of clusters on the drive (both free and used).


6. Return Value (Long)

  • If the function succeeds, it returns nonzero (1).

  • If it fails, it returns 0, and you can call Err.LastDllError to get more details.


How to Calculate Free Space

The free space (in bytes) can be calculated as:

Free Space = SectorsPerCluster × BytesPerSector × NumberOfFreeClusters

Similarly, total disk size can be calculated as:

Total Space = SectorsPerCluster × BytesPerSector × TotalNumberOfClusters


GetDiskFreeSpace` API usage into a **reusable VBA function**.

We’ll wrap it into a function `GetDriveSpace()` that you can call with any drive letter, and it will return **total space and free space in GB**

Step 1 – API Declaration

Keep this in a standard module (global):

#If VBA7 Then
    Declare PtrSafe Function GetDiskFreeSpace Lib "kernel32" _
        Alias "GetDiskFreeSpaceA" ( _
        ByVal lpRootPathName As String, _
        lpSectorsPerCluster As Long, _
        lpBytesPerSector As Long, _
        lpNumberOfFreeClusters As Long, _
        lpTotalNumberOfClusters As Long) As Long
#Else
    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
#End If

Step 2 – Reusable Function

We’ll create a function that takes a drive letter (like "C:\" or "D:\") and returns total space and free space.

The DiskFreeSpace Wrapper Function.

We have created a wrapper function DiskFreeSpace to call the Windows API GetDiskFreeSpace Function from within, to retrieve and calculate the free space on the disk. The disk or computer memory capacity-related quantitative terms that we normally use are Gigabytes, Megabytes, or Kilobytes for communicating. So, we need to convert the cluster values into these measurements.

  1. Create a new Standard Module in your Database.

  2. Copy and paste the above Windows API Code into the global declaration area of the Module.

    The DiskFreeSpace Function Code.

  3. Next, copy and paste the following User function code below the Windows API code in the same Module:

    Private SectorPerCluster As Long
    Private BytesPerSector As Long
    Private FreeClusters As Long
    Private TotalClusters As Long
    
    Private gbf As Double
    Private mbf As Double
    Private kbf As Double
    
    Private tb As Double
    Private gb As Double
    Private mb As Double
    Private kb As Double
    Private fmt As String
    Private msg As String, msg2 As String
    
    Public Function DiskFreeSpace(ByVal strPath As String) As String
    Dim Rtn As Long
    Dim ClusterBytes As Double
    
    On Error GoTo DiskFreeSpace_Err
    
    Rtn = GetDiskFreeSpace(strPath, SectorPerCluster, BytesPerSector, FreeClusters, TotalClusters)
    
    fmt = "#,##0"
    msg = ""
    msg2 = ""
    
    If Rtn Then
    
    'Bytes in a Cluster = Sectors * BytesPerSector
        ClusterBytes = SectorPerCluster * BytesPerSector 'Bytes per cluster
        
    'msg2 = "        Disk Drive: " & UCase(strPath) & vbCrLf & _
            "Sector Per Cluster: " & SectorPerCluster & vbCrLf & _
            "  Bytes Per Sector: " & BytesPerSector & vbCrLf & _
            "     Free Clusters: " & FreeClusters & vbCrLf & _
            "    Total Clusters: " & TotalClusters
            
    'Debug.Print msg2
    
        gbf = ClusterBytes / (1024# ^ 3) 'GB Factor per Cluster
        mbf = ClusterBytes / (1024# ^ 2) 'MB Factor     "
        kbf = ClusterBytes / (1024#)     'KB Factor     "
    
    'free Space
        tb = Int(TotalClusters * gbf) ' Total Space in Gigabytes
        gb = Int(FreeClusters * gbf)  ' Free Space  in     "
        mb = Int(FreeClusters * mbf)  '       "     in Megabytes
        kb = Int(FreeClusters * kbf)  '       "     in Kilobytes
    msg = " Disk Drive: " & UCase(strPath) & vbCrLf & _ "Total Space ( GB ): " & Format(tb, fmt) & vbCrLf & _ " Free Space ( GB ): " & Format(gb, fmt) & vbCrLf & _ " Free Space ( MB ): " & Format(mb, fmt) & vbCrLf & _ " Free Space ( KB ): " & Format(kb, fmt) Else MsgBox "Disk Drive PathName: " & UCase(strPath) & vbCrLf & _ "NOT FOUND!", vbOKOnly + vbCritical, "DiskFreeSpace()" DiskFreeSpace = "" Exit Function End If DiskFreeSpace = msg DiskFreeSpace_Exit: Exit Function DiskFreeSpace_Err: MsgBox Err & " : " & Err.Description, , "DiskFreeSpace()" DiskFreeSpace = "" Resume DiskFreeSpace_Exit End Function

Our new function needs only one parameter, the disk's Root Pathname.  If you look at the Windows API GetDiskFreeSpace Parameter declarations, the first Parameter is declared with ByVal qualification; other parameters are not qualified as such because they are declared as ByRef parameters by default.

The first parameter can be passed directly, like "C:\" or a variable initialized with the disk Root Pathname.  Other parameter variables are declared as Long Integer Types in the Global declaration area. These variable References are passed to the Windows API, and the retrieved information is saved directly into those Variables.

All Variables except Rtn and ClusterBytes I have declared at the global declaration area so that our own Function DiskFreeSpace Code looks better and less crowded.

The user-defined function DiskFreeSpace needs only one parameter: the Root Pathname of the disk, like "C:\".  The GetDiskFreeSpace Windows API is called with all five parameters from our function DiskFreeSpace().

The Disk Space Value Conversion Calculations.

If the API call was successful, then the variable Rtn will have the Value 1; otherwise, 0.

So testing the variable Rtn is necessary to proceed with converting the disk information into Gigabytes, Megabytes, or Kilobytes.

When the API is run successfully, the returned values are in Bytes per Sector, Sectors per Cluster, Disk Free Space in Clusters, and the Disk's total capacity in Clusters.  

The disk capacity is logically grouped into Sectors of 512 Bytes (characters) and a group of 8 Sectors or more known as a Cluster. This is the amount of data the computer can read/write in one attempt. This may change depending on the type of disk drives, like Hard Disk, SSD, Zip-Drive, or MicroSD Drive, and their formatting type: NTFS, FAT32, etc. 

The Bytes per Sector found 512 on most of the disk types, but the Sectors per cluster may change, like 8, 16, or 32.  You may test this function on your own machine with different Disk Types to find out.

We are familiar with the terms like Gigabytes (GB), Megabytes (MB), or Kilobytes (KB), the terms which we normally use to communicate the disk's capacity.  So we will convert the Clusters into bytes and then convert them into GB, MB, or KB.

[Total Bytes per Cluster] = [Bytes Per Sector] * [Sectors Per Cluster] = 512 * 8 = 4096 bytes.

GBF = [Total Bytes per Cluster] / (1024#^3): Gigabytes Factor.

MBF = [Total Bytes per Cluster] / (1024#^2): Megabytes Factor.

KBF = [Total Bytes per Cluster] / (1024#): KiloBytes Factor.

With these values, we can easily convert the Free Cluster Values into any of the above three Values, like:

GB = [Free Space Clusters] * GBF will give the Disk Free Space value in Gigabytes.

Our Function DiskFreeSpace() returns a String Value containing information formatted in such a way that the returned value can be displayed in a MsgBox, printed in the Debug Window, or displayed in a Label Control on a Form that is wide enough to display 5 lines of text.

The sample output Image in the Debug Window and in the MsgBox side-by-side is given below for information:

The DiskFreeSpace() function can be run from the Debug Window directly, from within some other function, or from an Event Procedure on Form.

The Demo Database is attached for Download and ready to run.



  1. MS-Access Class Module and VBA
  2. MS-Access VBA Class Object Arrays
  3. MS-Access Base Class and Derived Objects
  4. VBA Base Class and Derived Object-2
  5. Base Class and Derived Object Variants
  6. MS-Access Recordset and Class Module
  7. Access Class Module and Wrapper Classes
  8. Wrapper Class Functionality Transformation
Share:

PRESENTATION: ACCESS USER GROUPS (EUROPE)

Translate

PageRank

Post Feed


Search

Popular Posts

Blog Archive

Powered by Blogger.

Labels

Forms Functions How Tos MS-Access Security Reports msaccess forms Animations msaccess animation Utilities msaccess controls Access and Internet MS-Access Scurity MS-Access and Internet Class Module External Links Queries Array msaccess reports Accesstips WithEvents msaccess tips Downloads Objects Menus and Toolbars Collection Object MsaccessLinks Process Controls Art Work Property msaccess How Tos Combo Boxes Dictionary Object ListView Control Query VBA msaccessQuery Calculation Event Graph Charts ImageList Control List Boxes TreeView Control Command Buttons Controls Data Emails and Alerts Form Custom Functions Custom Wizards DOS Commands Data Type Key Object Reference ms-access functions msaccess functions msaccess graphs msaccess reporttricks Command Button Report msaccess menus msaccessprocess security advanced Access Security Add Auto-Number Field Type Form Instances ImageList Item Macros Menus Nodes RaiseEvent Recordset Top Values Variables Wrapper Classes msaccess email progressmeter Access2007 Copy Excel Export Expression Fields Join Methods Microsoft Numbering System Records Security Split SubForm Table Tables Time Difference Utility WScript Workgroup database function msaccess wizards tutorial Access Emails and Alerts Access Fields Access How Tos Access Mail Merge Access2003 Accounting Year Action Animation Attachment Binary Numbers Bookmarks Budgeting ChDir Color Palette Common Controls Conditional Formatting Data Filtering Database Records Defining Pages Desktop Shortcuts Diagram Disk Dynamic Lookup Error Handler External Filter Formatting Groups Hexadecimal Numbers Import Labels List Logo Macro Mail Merge Main Form Memo Message Box Monitoring Octal Numbers Operating System Paste Primary-Key Product Rank Reading Remove Rich Text Sequence SetFocus Summary Tab-Page Union Query User Users Water-Mark Word automatically commands hyperlinks iSeries Date iif ms-access msaccess msaccess alerts pdf files reference restore switch text toolbar updating upload vba code