Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Get Disk Drive Capacity
#1
Hi,
Years ago when I wrote assembler in GWBASIC or QuickBASIC there was INT &H21 to see how much free space you have left on the disk.
See also https://ftp.zx.net.nz/pub/archive/ftp.mi...46/980.HTM
Is there such a thing for QB64-PE with modern PC's like Windows 7 and up??

In C something like this? https://learn.microsoft.com/en-us/dotnet...ew=net-7.0
Reply
#2
Easiest way?  https://winaero.com/get-disk-drive-infor...s-command/

Just pipe the info to a temp file and read it.
Reply
#3
In QB64 you can use a Windows API for this.
Code: (Select All)

DECLARE DYNAMIC LIBRARY "kernel32"
        function GetDiskFreeSpaceEx% alias "GetDiskFreeSpaceExA" (_
        lpDirectoryName as STRING, _
        lpFreeBytesAvailableToMe As _UNSIGNED LONG, _
        lpTotalNumberOfBytes As _UNSIGNED LONG, _
        lpTotalNumberOfFreeBytes As _UNSIGNED LONG)
END DECLARE

DIM DriveOrFolder AS STRING
DIM FreeBytesAvailableToMe AS _UNSIGNED LONG
DIM TotalBytes AS _UNSIGNED LONG
DIM FreeBytes AS _UNSIGNED LONG


DriveOrFolder = "C:\"

FetchResult = GetDiskFreeSpaceEx(DriveOrFolder, FreeBytesAvailableToMe, TotalBytes, FreeBytes)

PRINT "Path: '" + DriveOrFolder + "'"
PRINT "Path founding (1 - ok, 0 - ERROR):" + STR$(FetchResult)
PRINT "------------------------------------"
PRINT "TotalBytes:              " + STR$(TotalBytes)
PRINT "FreeBytes Avilable To Me: " + STR$(FreeBytesAvailableToMe)
PRINT "FreeBytes:                " + STR$(FreeBytes)

Edit:
If you use the data type _UNSIGNED _INTEGER64, you can read larger disk sizes.
_UNSIGNED LONG is for < 4 GB media.
Reply
#4
(07-03-2023, 05:39 PM)SagaraS Wrote: In QB64 you can use a Windows API for this.
Code: (Select All)

DECLARE DYNAMIC LIBRARY "kernel32"
        function GetDiskFreeSpaceEx% alias "GetDiskFreeSpaceExA" (_
        lpDirectoryName as STRING, _
        lpFreeBytesAvailableToMe As _UNSIGNED LONG, _
        lpTotalNumberOfBytes As _UNSIGNED LONG, _
        lpTotalNumberOfFreeBytes As _UNSIGNED LONG)
END DECLARE

DIM DriveOrFolder AS STRING
DIM FreeBytesAvailableToMe AS _UNSIGNED LONG
DIM TotalBytes AS _UNSIGNED LONG
DIM FreeBytes AS _UNSIGNED LONG


DriveOrFolder = "C:\"

FetchResult = GetDiskFreeSpaceEx(DriveOrFolder, FreeBytesAvailableToMe, TotalBytes, FreeBytes)

PRINT "Path: '" + DriveOrFolder + "'"
PRINT "Path founding (1 - ok, 0 - ERROR):" + STR$(FetchResult)
PRINT "------------------------------------"
PRINT "TotalBytes:              " + STR$(TotalBytes)
PRINT "FreeBytes Avilable To Me: " + STR$(FreeBytesAvailableToMe)
PRINT "FreeBytes:                " + STR$(FreeBytes)

Edit:
If you use the data type _UNSIGNED _INTEGER64, you can read larger disk sizes.
_UNSIGNED LONG is for < 4 GB media.
I also found something like that.


Code: (Select All)

Option _Explicit

Const DRIVE_UNKNOWN = 0
Const DRIVE_NO_ROOT_DIR = 1
Const DRIVE_REMOVABLE = 2
Const DRIVE_FIXED = 3
Const DRIVE_REMOTE = 4
Const DRIVE_CDROM = 5
Const DRIVE_RAMDISK = 6

Declare Dynamic Library "Kernel32"
    Function GetDiskFreeSpace% Alias GetDiskFreeSpaceExA (lpDirectoryName As String, Byval lpFreeBytesAvailableToCaller As _Offset, Byval lpTotalNumberOfBytes As _Offset, Byval lpTotalNumberOfFreeBytes As _Offset)
    Function GetDriveType~& Alias GetDriveTypeA (lpRootPathName As String)
End Declare

Dim totalFreeBytesOnDisk As _Unsigned _Integer64

If GetDiskFreeSpace("C:\", 0, 0, _Offset(totalFreeBytesOnDisk)) Then
    Select Case totalFreeBytesOnDisk
        Case Is < 1024
            Print Using "    ####, B Available"; totalFreeBytesOnDisk,
        Case Is < (1024 ^ 2) And totalFreeBytesOnDisk >= 1024
            Print Using "####,.## KB Available"; (totalFreeBytesOnDisk / 1024)
        Case Is < (1024 ^ 3) And totalFreeBytesOnDisk >= (1024 ^ 2)
            Print Using "####,.## MB Available"; (totalFreeBytesOnDisk / (1024 ^ 2))
        Case Is < (1024 ^ 4) And totalFreeBytesOnDisk >= (1024 ^ 3)
            Print Using "####,.## GB Available"; (totalFreeBytesOnDisk / (1024 ^ 3))
        Case Is < (1024 ^ 5) And totalFreeBytesOnDisk >= (1024 ^ 4)
            Print Using "####,.## TB Available"; (totalFreeBytesOnDisk / (1024 ^ 4))
    End Select
End If

Select Case GetDriveType("C:\")
    Case DRIVE_UNKNOWN
        Print "Unkown drive type"
    Case DRIVE_NO_ROOT_DIR
        Print "Invalid path"
    Case DRIVE_REMOVABLE
        Print "Removable media"
    Case DRIVE_FIXED
        Print "Fixed media"
    Case DRIVE_REMOTE
        Print "Network media"
    Case DRIVE_CDROM
        Print "CD-ROM drive"
    Case DRIVE_RAMDISK
        Print "RAM disk"
End Select
Reply
#5
@Stefan-68 It's definitely a step further. ^^
Reply
#6
Quote:I also found something like that.
@Stefan-68, useful program. Did you program it yourself or where did you find it? The explanation would be important to me with regard to the declaration of the "library".

I have modified it a bit so that one can specify the drives.

Code: (Select All)
'Stefan68, Belegung eines Speichermediums ermitteln - 3. Juli 2023

Option _Explicit

Const DRIVE_UNKNOWN = 0
Const DRIVE_NO_ROOT_DIR = 1
Const DRIVE_REMOVABLE = 2
Const DRIVE_FIXED = 3
Const DRIVE_REMOTE = 4
Const DRIVE_CDROM = 5
Const DRIVE_RAMDISK = 6

Declare Dynamic Library "Kernel32"
  Function GetDiskFreeSpace% Alias GetDiskFreeSpaceExA (lpDirectoryName As String, Byval lpFreeBytesAvailableToCaller As _Offset, Byval lpTotalNumberOfBytes As _Offset, Byval lpTotalNumberOfFreeBytes As _Offset)
  Function GetDriveType~& Alias GetDriveTypeA (lpRootPathName As String)
End Declare

Dim totalFreeBytesOnDisk As _Unsigned _Integer64
Dim laufwerk As String * 3

Locate 3, 3
Print "Zeigt die Belegung der Laufwerke an"
Locate 4, 3
Print "==================================="

Locate 6, 3
Input "Laufwerksbustabe (z.B. C:): ", laufwerk

Locate CsrLin + 1, 3
If GetDiskFreeSpace(laufwerk, 0, 0, _Offset(totalFreeBytesOnDisk)) Then
  Select Case totalFreeBytesOnDisk
    Case Is < 1024
      Print Using "    ####, B Available"; totalFreeBytesOnDisk,
    Case Is < (1024 ^ 2) And totalFreeBytesOnDisk >= 1024
      Print Using "####,.## KB Available"; (totalFreeBytesOnDisk / 1024)
    Case Is < (1024 ^ 3) And totalFreeBytesOnDisk >= (1024 ^ 2)
      Print Using "####,.## MB Available"; (totalFreeBytesOnDisk / (1024 ^ 2))
    Case Is < (1024 ^ 4) And totalFreeBytesOnDisk >= (1024 ^ 3)
      Print Using "####,.## GB Available"; (totalFreeBytesOnDisk / (1024 ^ 3))
    Case Is < (1024 ^ 5) And totalFreeBytesOnDisk >= (1024 ^ 4)
      Print Using "####,.## TB Available"; (totalFreeBytesOnDisk / (1024 ^ 4))
  End Select
End If

Locate CsrLin + 2, 3
Beep
Select Case GetDriveType(laufwerk)
  Case DRIVE_UNKNOWN
    Print "Unkown drive type"
  Case DRIVE_NO_ROOT_DIR
    Print "Invalid path"
  Case DRIVE_REMOVABLE
    Print "Removable media"
  Case DRIVE_FIXED
    Print "Fixed media"
  Case DRIVE_REMOTE
    Print "Network media"
  Case DRIVE_CDROM
    Print "CD-ROM drive"
  Case DRIVE_RAMDISK
    Print "RAM disk"
End Select
Reply
#7
I think the code Steffan shared is code I wrote a long time ago. Glad to see it was able to do its job.
Schuwatch!
Yes, it's me. Now shut up.
Reply
#8
I've edited my original code to be slightly cleaner by using CONSTs for the KILOBYTE, MEGABYTE, etc. I've also put the aliased names in quotes, to make them easier to read. I've also changed the library declaration from using the Kernel32 DLL to just using the headers in the QB64 folder. I've also changed GetDiskFreeSpace from an INTEGER to LONG, as the return type is BOOL, which is 4 bytes.

Code: (Select All)

Option _Explicit

Const DRIVE_UNKNOWN = 0
Const DRIVE_NO_ROOT_DIR = 1
Const DRIVE_REMOVABLE = 2
Const DRIVE_FIXED = 3
Const DRIVE_REMOTE = 4
Const DRIVE_CDROM = 5
Const DRIVE_RAMDISK = 6

Const KILOBYTE = 1024
Const MEGABYTE = KILOBYTE ^ 2
Const GIGABYTE = KILOBYTE ^ 3
Const TERABYTE = KILOBYTE ^ 4
Const PETABYTE = KILOBYTE ^ 5

Declare CustomType Library
    Function GetDiskFreeSpace& Alias "GetDiskFreeSpaceExA" (lpDirectoryName As String, Byval lpFreeBytesAvailableToCaller As _Offset, Byval lpTotalNumberOfBytes As _Offset, Byval lpTotalNumberOfFreeBytes As _Offset)
    Function GetDriveType~& Alias "GetDriveTypeA" (lpRootPathName As String)
End Declare

Dim As _Unsigned _Integer64 totalFreeBytesOnDisk

If GetDiskFreeSpace("C:\", 0, 0, _Offset(totalFreeBytesOnDisk)) Then
    Select Case totalFreeBytesOnDisk
        Case Is < KILOBYTE
            Print Using "    ####, B Available"; totalFreeBytesOnDisk,
        Case Is < MEGABYTE And totalFreeBytesOnDisk >= KILOBYTE
            Print Using "####,.## KB Available"; (totalFreeBytesOnDisk / KILOBYTE)
        Case Is < GIGABYTE And totalFreeBytesOnDisk >= MEGABYTE
            Print Using "####,.## MB Available"; (totalFreeBytesOnDisk / MEGABYTE)
        Case Is < TERABYTE And totalFreeBytesOnDisk >= GIGABYTE
            Print Using "####,.## GB Available"; (totalFreeBytesOnDisk / GIGABYTE)
        Case Is < PETABYTE And totalFreeBytesOnDisk >= TERABYTE
            Print Using "####,.## TB Available"; (totalFreeBytesOnDisk / TERABYTE)
    End Select
End If

Select Case GetDriveType("C:\")
    Case DRIVE_UNKNOWN
        Print "Unkown drive type"
    Case DRIVE_NO_ROOT_DIR
        Print "Invalid path"
    Case DRIVE_REMOVABLE
        Print "Removable media"
    Case DRIVE_FIXED
        Print "Fixed media"
    Case DRIVE_REMOTE
        Print "Network media"
    Case DRIVE_CDROM
        Print "CD-ROM drive"
    Case DRIVE_RAMDISK
        Print "RAM disk"
End Select
Schuwatch!
Yes, it's me. Now shut up.
Reply
#9
(07-05-2023, 03:56 PM)Ultraman Wrote: I think the code Steffan shared is code I wrote a long time ago. Glad to see it was able to do its job.
Ah ok. Works great. And these are variables: "lpFreeBytesAvailableToCaller"? I really need to take a closer look at this ByVal.

PS: The new version is even better! I will it add. Thanks!  Exclamation
Reply
#10
As I mentioned before, here's what I find to be the easiest way:

Code: (Select All)
Shell "wmic logicaldisk get Name, Description, Size>temp.txt"

Gives a text file which looks like:
Quote:Description      Name  Size         
Local Fixed Disk  C:    493559476224 
Local Fixed Disk  D:    2000263573504 
CD-ROM Disc      F:                 
Local Fixed Disk  Z:    8589930496   
Reply




Users browsing this thread: 3 Guest(s)