by Michael Rüsweg-Gilbert
To get the amount of available disk space you can call GetDiskFreeSpace or GetDiskFreeSpaceEx.
GetDiskFreeSpaceEx is best because it supports disks larger than 2 gigabyte. Unfortunately this function may not be available on every Windows version (Windows 95 before OSR2 only supports GetDiskFreeSpace).
The following program shows how to call GetDiskFreeSpaceEx. Note how the 64-bit parameters are cast in MEMPTR variables and converted to decimal values.
/* =============================================================================== Program: VolSpace.p Created: Michael R?Gilbert Feb 2001 mailto:rg@rgilbert.de Description: returns the capacity and free space of a volume (even if Vol > 2 GB) Usage: for ex. run VolSpace.p ("C:", "KB", output freeSpace, output totalSpace). Parameters: - Volume to check or Blank (Blank returns informations abaout the working drirector drive) It does not have to be the root, accepts any directory. - Unit to format the result; legal entries are "KB", "MB" or "GB". If the unit is not recognized or empty, VolSpace will return Number of Bytes. - OUTPUT available free space in given unit - OUTPUT total space in given unit When VolSpace is not successful, both output parameters will return ?. modifications: March 14, 2001: Jurjen - added function IsAPIFunctionSupported() ===================================================================================== */ DEFINE INPUT PARAMETER ip_drive AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER ip_unit AS CHARACTER NO-UNDO. DEFINE OUTPUT PARAMETER op_free AS DECIMAL NO-UNDO. DEFINE OUTPUT PARAMETER op_total AS DECIMAL NO-UNDO. &SCOPED-DEFINE WTRUE 1 &SCOPED-DEFINE WFALSE 0 FUNCTION get64BitValue RETURNS DECIMAL (INPUT m64 AS MEMPTR) FORWARD. FUNCTION IsAPIFunctionSupported RETURNS LOGICAL (FunctionName AS CHAR, ModuleName AS CHARACTER) FORWARD. DEFINE VARIABLE retval AS INTEGER NO-UNDO. DEFINE VARIABLE divident AS INTEGER NO-UNDO INIT 1. DEFINE VARIABLE i AS INTEGER NO-UNDO. DEFINE VARIABLE mem1 AS MEMPTR NO-UNDO. DEFINE VARIABLE mem2 AS MEMPTR NO-UNDO. DEFINE VARIABLE mem3 AS MEMPTR NO-UNDO. /* See if GetDiskFreeSpaceEx is available in this Windows version. (it is available in NT4, Windows 95 OSR2, Windows 98, Windows 2000) */ IF NOT IsAPIFunctionSupported("GetDiskFreeSpaceExA":U, "kernel32.dll":U) THEN DO: MESSAGE "Sorry, your version of Windows does not support GetDiskFreeSpaceEx" VIEW-AS ALERT-BOX. ASSIGN op_free = ? op_total = ?. RETURN. END. IF CAN-DO("KB,Kilo,Kilobyte,Kilobytes", ip_unit) THEN divident = 1024. ELSE IF CAN-DO("MB,Mega,Megabyte,Megabytes", ip_unit) THEN divident = 1024 * 1024. ELSE IF CAN-DO("GB,Giga,Gigabyte,Gigabytes", ip_unit) THEN divident = 1024 * 1024 * 1024. ELSE divident = 1. /* No directory specified? Then use the current directory */ IF (ip_drive = "") OR (ip_drive=?) THEN DO: FILE-INFO:FILE-NAME = ".". ip_drive = FILE-INFO:FULL-PATHNAME. END. /* If a UNC name was specified, make sure it ends with a backslash ( \\drive\share\dir\ ) This won't hurt for a mapped drive too */ IF SUBSTR(ip_drive, LENGTH(ip_drive), 1) NE "\" THEN ip_drive = ip_drive + "\". SET-SIZE(mem1) = 8. /* 64 bit integer! */ SET-SIZE(mem2) = 8. SET-SIZE(mem3) = 8. RUN GetDiskFreeSpaceExA ( ip_drive + CHR(0), OUTPUT mem1, OUTPUT mem2, OUTPUT mem3, OUTPUT retVal ). IF retVal NE {&WTRUE} THEN DO: op_free = ?. op_total = ?. END. ELSE DO: ASSIGN op_free = TRUNC( get64BitValue(mem3) / divident, 3) op_total = TRUNC( get64BitValue(mem2) / divident, 3). END. SET-SIZE(mem1) = 0. SET-SIZE(mem2) = 0. SET-SIZE(mem3) = 0. RETURN. PROCEDURE GetModuleHandleA EXTERNAL "kernel32.dll" : DEFINE INPUT PARAMETER lpModuleName AS CHARACTER NO-UNDO. DEFINE RETURN PARAMETER hModule AS LONG NO-UNDO. END PROCEDURE. PROCEDURE GetProcAddress EXTERNAL "kernel32.dll" : DEFINE INPUT PARAMETER hModule AS LONG NO-UNDO. DEFINE INPUT PARAMETER lpProcName AS CHARACTER NO-UNDO. DEFINE RETURN PARAMETER lpFarproc AS LONG NO-UNDO. END PROCEDURE. PROCEDURE GetDiskFreeSpaceExA EXTERNAL "kernel32.dll" : DEFINE INPUT PARAMETER lpDirectoryName AS CHARACTER NO-UNDO. DEFINE OUTPUT PARAMETER FreeBytesAvailable AS MEMPTR NO-UNDO. DEFINE OUTPUT PARAMETER TotalNumberOfBytes AS MEMPTR NO-UNDO. DEFINE OUTPUT PARAMETER TotalNumberOfFreeBytes AS MEMPTR NO-UNDO. DEFINE RETURN PARAMETER retval AS LONG NO-UNDO. END PROCEDURE. /* See if GetDiskFreeSpaceEx is available in this Windows version */ FUNCTION IsAPIFunctionSupported RETURNS LOGICAL (FunctionName AS CHAR, ModuleName AS CHARACTER): DEFINE VARIABLE hModule AS INTEGER NO-UNDO. DEFINE VARIABLE lpFarProc AS INTEGER NO-UNDO. /* you should run LoadLibraryA to load the module into memory, but this is not necessary for ModuleName="kernel32.dll": the kernel is always available. */ RUN GetModuleHandleA (ModuleName, OUTPUT hModule). RUN GetProcAddress (hModule, FunctionName, OUTPUT lpFarProc). RETURN lpFarProc NE 0. END FUNCTION. /* Converts a 64-bit integer given in a 8 byte mempointer into a decimal */ FUNCTION get64BitValue RETURNS DECIMAL ( INPUT m64 AS MEMPTR ): /* constant 2^32 */ &SCOPED-DEFINE BigInt 4294967296 DEFINE VARIABLE d1 AS DECIMAL NO-UNDO. DEFINE VARIABLE d2 AS DECIMAL NO-UNDO. d1 = GET-LONG(m64, 1). IF d1 < 0 THEN d1 = d1 + {&BigInt}. d2 = GET-LONG(m64, 5). IF d2 < 0 THEN d2 = d2 + {&BigInt}. IF d2 GT 0 THEN d1 = d1 + (d2 * {&BigInt}). RETURN d1. END FUNCTION.