Page 1 of 2

Getting Free Disk Space

Posted: Thu Sep 13, 2012 6:07 pm
by Michael42
Hello,

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

Thanks,

Michael

Re: Getting Free Disk Space

Posted: Thu Sep 13, 2012 7:14 pm
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

Re: Getting Free Disk Space

Posted: Thu Sep 13, 2012 7:23 pm
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"

Re: Getting Free Disk Space

Posted: Sun May 25, 2014 11:58 am
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

Re: Getting Free Disk Space

Posted: Sun May 25, 2014 3:26 pm
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)

Re: Getting Free Disk Space

Posted: Sun May 25, 2014 4:20 pm
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

Re: Getting Free Disk Space

Posted: Sun May 25, 2014 5:27 pm
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

Re: Getting Free Disk Space

Posted: Mon May 26, 2014 5:53 am
by NY152
Strange ... This returns me completely absurbe values ​​:/

Re: Getting Free Disk Space

Posted: Mon May 26, 2014 9:44 am
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)

Re: Getting Free Disk Space

Posted: Tue May 27, 2014 12:10 am
by NY152
Thank you it works well (except for the free disk space (negative value))

Otherwise it's perfect :)

Re: Getting Free Disk Space

Posted: Tue May 27, 2014 12:25 am
by Thunder93
Do the same thing to the rest as I've done with TotalBytes

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

Re: Getting Free Disk Space

Posted: Tue May 27, 2014 12:33 am
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:

Re: Getting Free Disk Space

Posted: Tue May 27, 2014 12:48 am
by Thunder93
Crying out loud! It was already posted here anyways. :lol:

Re: Getting Free Disk Space

Posted: Tue May 27, 2014 12:58 am
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)

Re: Getting Free Disk Space

Posted: Tue May 27, 2014 1:15 am
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)