Getting Free Disk Space

Windows specific forum
Michael42
User
User
Posts: 11
Joined: Thu Aug 30, 2012 3:12 am

Getting Free Disk Space

Post by Michael42 »

Hello,

How can I get free disk space for any particular drive using PB?

Thanks,

Michael
User avatar
luis
Addict
Addict
Posts: 3876
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Getting Free Disk Space

Post by luis »

http://support.microsoft.com/kb/202455

Code: Select all

EnableExplicit

Define lpFreeBytesAvailableToCaller.q,  lpTotalNumberOfBytes.q, lpTotalNumberOfFreeBytes.q	
GetDiskFreeSpaceEx_("C:", @lpFreeBytesAvailableToCaller, @lpTotalNumberOfBytes, @lpTotalNumberOfFreeBytes)

Debug lpFreeBytesAvailableToCaller
Debug lpTotalNumberOfBytes
Debug lpTotalNumberOfFreeBytes

EDIT: beautyfied

Code: Select all

Procedure.i GetDiskFreeSpace (drive$, *UserFreeSpace, *TotalSpace, *FreeSpace = #Null)
; [DESC]
; Return the free space for the specified local ("C:\") or networked ("\\ARCHIMEDE\SHARE\") volume.
;
; [INPUT]
; drive$ : Points to a string that contains the root directory of the volume to be described. 
;
; [OUTPUT]
; *UserFreeSpace : Pointer to a quad, it will contain the free space available for the user of this process (in case of quotas).
; *TotalSpace : Pointer to a quad, it will contain the total space (free + used) for the volume.
; *FreeSpace : Pointer to a quad, it will contain the free space available for the volume. 
; 	
; [RETURN]
; 1 if OK, else 0.
;
; [NOTES]
; If drive$ is empty, the root of the current directory is used. 
; if *FreeSpace is #Null it will be skipped (it's optional).

 If drive$ = ""
    drive$ = Left(GetCurrentDirectory(),3)
 EndIf
 
 If GetDiskFreeSpaceEx_(drive$, *UserFreeSpace, *TotalSpace, *FreeSpace)
    ProcedureReturn 1
 EndIf

 ProcedureReturn 0
EndProcedure


Define.q UserFreeSpace, TotalSpace, FreeSpace 

Debug GetDiskFreeSpace ("D:\", @UserFreeSpace, @TotalSpace, @FreeSpace)

Debug UserFreeSpace
Debug TotalSpace
Debug FreeSpace 

Debug GetDiskFreeSpace ("", @UserFreeSpace, @TotalSpace)

Debug UserFreeSpace
Debug TotalSpace
Last edited by luis on Thu Sep 13, 2012 8:34 pm, edited 1 time in total.
"Have you tried turning it off and on again ?"
A little PureBasic review
eJan
Enthusiast
Enthusiast
Posts: 365
Joined: Sun May 21, 2006 11:22 pm
Location: Sankt Veit am Flaum

Re: Getting Free Disk Space

Post by eJan »

Also:

Code: Select all

; freak: http://www.purearea.net/pb/CodeArchiv/Windows_System/Hardware/GetDiskFreeSpace.pb

Structure int64
  Long1.l
  Long2.l
EndStructure

drive$ = "C:\"

; this prevents the 'please insert drive' requester.
; GetDiskFreeSpaceEx_() will just return 0 if the drive is not avaiable,
; without a prompt to the user :
SetErrorMode_(#SEM_FAILCRITICALERRORS)


If GetDiskFreeSpaceEx_(@drive$, BytesFreeToCaller.int64, TotalBytes.int64, TotalFreeBytes.int64) = 0
  MessageRequester("", "Drive not ready!", 0)
  End
EndIf

; reset the error behaviour
SetErrorMode_(0)

; calculate sizes in mb.
TotalMB = ((TotalBytes\Long1 >> 20) & $FFF) | (TotalBytes\Long2 << 12)
FreeMB = ((TotalFreeBytes\Long1 >> 20) & $FFF) | (TotalFreeBytes\Long2 << 12)

Debug "Disk : " + drive$
Debug "Size : " + Str(TotalMB) + " Mb"
Debug "Free : " + Str(FreeMB) + " Mb"

Code: Select all

; PB: http://www.purebasic.fr/english/viewtopic.php?p=129208

; r=GetDiskSpace("c : ", "t") ; Get number of total bytes on C :
; r=GetDiskSpace("c : ", "f") ; Get number of free bytes on C :
; r=GetDiskSpace("c : ", "u") ; Get number of used bytes on C :
;
; r = -1 on failure (eg. drive not found, or bad type$ param).

Procedure.q GetDiskSpace(drive$, type$)
  value.q = - 1
  If GetDiskFreeSpaceEx_(drive$, @free.q, @total.q, 0)
    Select LCase(type$)
      Case "t" : value = total
      Case "f" : value = free
      Case "u" : value = total - free
      Default : value = - 1
    EndSelect
  EndIf
  ProcedureReturn value
EndProcedure

drive.s = "C:"

Debug Str(GetDiskSpace(drive, "t")) + " Total"
Debug Str(100 * GetDiskSpace(drive, "u") / GetDiskSpace(drive, "t")) + " % Used"
Debug Str(100 * GetDiskSpace(drive, "f") / GetDiskSpace(drive, "t")) + " % Free"
Image
NY152
User
User
Posts: 29
Joined: Sun May 14, 2006 12:33 am

Re: Getting Free Disk Space

Post by NY152 »

eJan Excellent but I'm lost for conversion in Mb. I would like to have a good unit based on the quantity (Kb, Mb, Gb ... etc)

If you can show me how to StrFormatByteSize64_ () for example?

Thank you in advance
.:NY152:.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Getting Free Disk Space

Post by Thunder93 »

Hi NY152.

This API way.. Example following. This should work for Windows (x64 & x86) w/Ascii or w/Unicode modes.

Code: Select all

Prototype StrFormatByteSize64(num.q, *buffer, length.l)

Global StrFormatByteSize64.StrFormatByteSize64

Procedure.i shlwapi_LoadDLL()
  Protected hDLL.i

  hDLL = OpenLibrary(#PB_Any, "shlwapi.dll")
  If hDLL <> 0
    
    StrFormatByteSize64 = GetFunction(hDLL, "StrFormatByteSize64A")

    ProcedureReturn hDLL
  EndIf

  ProcedureReturn #False
EndProcedure : shlwapi_LoadDLL()

Procedure.s StrFormatSize(num.q)
  Protected *string, buf.s = Space(255)
  
  *string = StrFormatByteSize64(num, @buf, 255)
  
  If *string
    ProcedureReturn PeekS(*string, -1, #PB_Ascii)
  EndIf
  
EndProcedure


Debug StrFormatSize(1000)
Debug StrFormatSize(10000)
Debug StrFormatSize(1000000)
Debug StrFormatSize(100000000)
Debug StrFormatSize(10000000000)
Debug StrFormatSize(10000000000000)
Debug StrFormatSize(10000000000000000)

However a preferred way for couple of reasons.., I use the following.

Code: Select all

Procedure.s SizeIt(Value.q)  
  Protected unit.b=0, byte.q, nSize.s
  
  byte = Value
  While byte >= 1024
    byte / 1024 : unit + 1
  Wend
  
  If unit : nSize = StrD(Value/Pow(1024, unit), 15) : pos.l = FindString(nSize, ".") : Else : nSize = Str(Value) : EndIf
  
  If unit : If pos <  4 : nSize=Mid(nSize,1,pos+2) : Else : nSize = Mid(nSize, 1, pos-1) : EndIf : EndIf
  
  ProcedureReturn nSize+" "+StringField("bytes,KB,MB,GB,TB,PB", unit+1, ",")  
EndProcedure


Debug SizeIt(1000)
Debug SizeIt(10000)
Debug SizeIt(1000000)
Debug SizeIt(100000000)
Debug SizeIt(10000000000)
Debug SizeIt(10000000000000)
Debug SizeIt(10000000000000000)
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
NY152
User
User
Posts: 29
Joined: Sun May 14, 2006 12:33 am

Re: Getting Free Disk Space

Post by NY152 »

Thank you for this code but this is not what I asked :)

In your code that retrieves the size of the disk, I do not understand how to get the raw size (without conversion Mb)


PS : sorry for my very bad (automated lol) translation :P
.:NY152:.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Getting Free Disk Space

Post by Thunder93 »

OK! lol

So nothing fancy is done so reading TotalBytes will give number in bytes form.

Code: Select all

TotalBytes.q

GetDiskFreeSpaceEx_(@drive$, BytesFreeToCaller.int64, @TotalBytes, TotalFreeBytes.int64)
:P
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
NY152
User
User
Posts: 29
Joined: Sun May 14, 2006 12:33 am

Re: Getting Free Disk Space

Post by NY152 »

Strange ... This returns me completely absurbe values ​​:/
.:NY152:.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Getting Free Disk Space

Post by Thunder93 »

On my end it works perfectly...

My C:\ Drive is 1.35 TB. In bytes its 1485928656896


Let's have a look at the compiled code Results:
My C:\ Drive Total Size (in bytes): 1485928656896
My C:\ Drive Total Size (..converted over from bytes): 1.35 TB



Is perfect read.

Here is the working example.

Code: Select all

Structure int64
  Long1.l
  Long2.l
EndStructure

drive$ = "C:\"

SetErrorMode_(#SEM_FAILCRITICALERRORS)

TotalBytes.q

If GetDiskFreeSpaceEx_(@drive$, BytesFreeToCaller.int64, @TotalBytes, TotalFreeBytes.int64) = 0
  MessageRequester("", "Drive not ready!", 0)
  End
EndIf

SetErrorMode_(0)

Debug "My C:\ Drive Total Size (in bytes): "+Str(TotalBytes)

Procedure.s SizeIt(Value.q)  
  Protected unit.b=0, byte.q, nSize.s
  
  byte = Value
  While byte >= 1024
    byte / 1024 : unit + 1
  Wend
  
  If unit : nSize = StrD(Value/Pow(1024, unit), 15) : pos.l = FindString(nSize, ".") : Else : nSize = Str(Value) : EndIf
  
  If unit : If pos <  4 : nSize=Mid(nSize,1,pos+2) : Else : nSize = Mid(nSize, 1, pos-1) : EndIf : EndIf
  
  ProcedureReturn nSize+" "+StringField("bytes,KB,MB,GB,TB,PB", unit+1, ",")  
EndProcedure


Debug "My C:\ Drive Total Size (..converted over from bytes): "+SizeIt(TotalBytes)
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
NY152
User
User
Posts: 29
Joined: Sun May 14, 2006 12:33 am

Re: Getting Free Disk Space

Post by NY152 »

Thank you it works well (except for the free disk space (negative value))

Otherwise it's perfect :)
.:NY152:.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Getting Free Disk Space

Post by Thunder93 »

Do the same thing to the rest as I've done with TotalBytes

GetDiskFreeSpaceEx_(@drive$, @BytesFreeToCaller, @TotalBytes, @TotalFreeBytes)
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
luis
Addict
Addict
Posts: 3876
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Getting Free Disk Space

Post by luis »

@NY152

Ehm, what's wrong with the first code in the second post of this thread ?

Isn't that already returning what you are looking for from 2012 ?

It's late here, am I missing something ? It's possible.... ronf :lol:
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Getting Free Disk Space

Post by Thunder93 »

Crying out loud! It was already posted here anyways. :lol:
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
NY152
User
User
Posts: 29
Joined: Sun May 14, 2006 12:33 am

Re: Getting Free Disk Space

Post by NY152 »

Yes i am


GetDiskFreeSpaceEx_(@drive$, @BytesFreeToCaller, @TotalBytes, @TotalFreeBytes)

but I still have a negative value and when the value is not negative, it is much lower than the reality (as 900MB instead of 400 GB)
.:NY152:.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Getting Free Disk Space

Post by Thunder93 »

It should be working... Regardless if you using Windows x64 or x86, PB x64 or x86, Unicode or Ascii Modes


My C:\ Drive Total Size (in bytes): 1485928656896
My C:\ Drive Total Size (..converted over from bytes): 1.35 TB
BytesFreeToCaller: 974 GB
TotalFreeBytes: 974 GB



Negative values.., you using PB x86 and have not assigned quad type?

Code: Select all

Drive$ = "C:\"

SetErrorMode_(#SEM_FAILCRITICALERRORS)

Define.q BytesFreeToCaller, TotalBytes, TotalFreeBytes

If GetDiskFreeSpaceEx_(@Drive$, @BytesFreeToCaller, @TotalBytes, @TotalFreeBytes) = 0
  MessageRequester("", "Drive not ready!", 0)
  End
EndIf

SetErrorMode_(0)

Debug "My C:\ Drive Total Size (in bytes): "+Str(TotalBytes)

Procedure.s SizeIt(Value.q)  
  Protected unit.b=0, byte.q, nSize.s
  
  byte = Value
  While byte >= 1024
    byte / 1024 : unit + 1
  Wend
  
  If unit : nSize = StrD(Value/Pow(1024, unit), 15) : pos.l = FindString(nSize, ".") : Else : nSize = Str(Value) : EndIf
  
  If unit : If pos <  4 : nSize=Mid(nSize,1,pos+2) : Else : nSize = Mid(nSize, 1, pos-1) : EndIf : EndIf
  
  ProcedureReturn nSize+" "+StringField("bytes,KB,MB,GB,TB,PB", unit+1, ",")  
EndProcedure


Debug "My C:\ Drive Total Size (..converted over from bytes): "+SizeIt(TotalBytes)

Debug "BytesFreeToCaller: "+SizeIt(BytesFreeToCaller)
Debug "TotalFreeBytes: "+SizeIt(TotalFreeBytes)
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
Post Reply