We help IT Professionals succeed at work.

diskfreespace

titz
titz asked
on
455 Views
Last Modified: 2010-04-04
hallo to all,

under D3/WIN98 i tried to determine the size of a disk
with the function getdiskfreespace.

i always receive freeclusters=65526 and totalclusters=65526.
but there are large disks (6 GB, 8 GB). that cannot be correct !

i think the problem is, that perhaps the function returns
only integer-values and no longint-values.

any idea how i can get the correct disksize ?

thanks
titz
Comment
Watch Question

RBertoraTech Director
CERTIFIED EXPERT

Commented:
Hi, straight from
the win32 help:


The GetDiskFreeSpace function returns incorrect values for volumes that are larger than 2 gigabytes. The function caps the values stored into *lpNumberOfFreeClusters and *lpTotalNumberOfClusters so as to never report volume sizes that are greater than 2 gigabytes.


BOOL GetDiskFreeSpaceEx(

    LPCTSTR lpDirectoryName,      // pointer to directory name on disk of interest  
    PULARGE_INTEGER lpFreeBytesAvailableToCaller,      // pointer to variable to receive free bytes on disk available to the caller
    PULARGE_INTEGER lpTotalNumberOfBytes,      // pointer to variable to receive number of bytes on disk
    PULARGE_INTEGER lpTotalNumberOfFreeBytes      // pointer to variable to receive free bytes on disk
   );      
 

Parameters

lpDirectoryName

Pointer to a null-terminated string that specifies a directory on the disk of interest. This string can be a UNC name.

If lpDirectoryName is NULL, the GetDiskFreeSpaceEx function obtains information about the disk that contains the currect directory.
Note that lpDirectoryName does not have to specify the root directory on a disk. The function accepts any directory on the disk.

lpFreeBytesAvailableToCaller

Pointer to a variable to receive the total number of free bytes on the disk that are available to the user associated with the calling thread.

If the operating system implements per-user quotas, this value may be less than the total number of free bytes on the disk.

lpTotalNumberOfBytes

Pointer to a variable to receive the total number of bytes on the disk.

lpTotalNumberOfFreeBytes

Pointer to a variable to receive the total number of free bytes on the disk.
This parameter can be NULL.

Rob;-)
RBertoraTech Director
CERTIFIED EXPERT

Commented:
ie try
GetDiskFreeSpaceEx

Author

Commented:
hi,

i have D3 and there is no such thing like PULARGE_INTEGER. maybe in D4 or D5.
even my help does not know the getdiskfreespaceex-
call.

to define these variables as longint is not possible
and a larger size is in D3 not possible. or ?

any idea ?

thanks
titz

Commented:
In Delphi 3 use COMP in leiu of PULARGE_INTEGER.


 

Commented:
also, you couled just define the LargeInteger yourself.. it's just another type:

Type
  _LARGE_INTEGER = record
    case Integer of
    0: (
      LowPart: DWORD;
      HighPart: Longint);
    1: (
      QuadPart: LONGLONG);
  end;


Good luck!!

Commented:
I don't know if Delphi 3 has the DiskFree function but this one returns an int64.

Author

Commented:
hi,

the correct parameters for getdiskfreespaceex in D3 are:
LPCTSTR  name
freebytesavailable : integer
totalnumberofbytes : integer
totalnumberofbytesfree  : Pinteger

only with these definitions a compilation was possible.
(COMP or _large_inter does not work for compilation-errors).
but the result was not correct, for the totalnumberofbytes
is an integer. and this is to small for 6Gbyte.
that is the same problem i started with.

any other ideas ?
i have none.

by the way: under WIN2000 the
function getfreediskspace works correct !

thanks
titz


Commented:
Does Delphi 3 have the DiskFree function (see also my previous comment)?

Commented:
From the WinAPI help file:

BTW, the function is NOT Delphi version dependent, only the datatypes are. For this I suggested that you define your own LargeInteger record.



BOOL GetDiskFreeSpaceEx(

    LPCTSTR lpDirectoryName,      // pointer to directory name on disk of interest  
    PULARGE_INTEGER lpFreeBytesAvailableToCaller,      // pointer to variable to receive free bytes on disk available to the caller
    PULARGE_INTEGER lpTotalNumberOfBytes,      // pointer to variable to receive number of bytes on disk
    PULARGE_INTEGER lpTotalNumberOfFreeBytes      // pointer to variable to receive free bytes on disk
   );      
 

Commented:
Hi titz,

I pass by troulbles with Win95a and the metions forgeten it.
well I'm using this, if int64 ins'nt supported by your compiler use extended type.

{Retorna o espaco livre de uma unidade de disco}
function _DiskFree( Drive : byte ) : int64;
var
  RootPath: array[0..4] of Char;
  RootPtr: PChar;
  SectorsPerCluster, BytesPerSector, FreeClusters, TotalClusters: cardinal;
  OS : OSVERSIONINFO;
  TotalFree, TotalExisting : int64;
begin
      RootPtr := nil;
      if Drive > 0 then
      begin
        StrCopy(RootPath, 'A:\');
        RootPath[0] := Char(Drive + $40);
        RootPtr := RootPath;
      end;
      OS.dwOSVersionInfoSize:=SizeOf(OSVERSIONINFO);
      GetVersionEx( OS );
      if (OS.dwMajorVersion = 4) and ( OS.dwBuildNumber < 1000) and ( OS.dwPlatformId = 1) then begin //Usar modo do OSR1
            if GetDiskFreeSpace(RootPtr, SectorsPerCluster, BytesPerSector, FreeClusters, TotalClusters) then begin
                  Result := (SectorsPerCluster * BytesPerSector * FreeClusters);
            end else begin
                  Result := -1;
            end;
      end else begin //Usar os servicos do NT ou Win95B ou superior
            if not GetDiskFreeSpaceEx(RootPtr,Result , TotalExisting, @TotalFree) then begin
                  Result := -1;
            end;
      end;
end;

T++, Radler.

Author

Commented:
hi,

now there several answers and i tried all:

epsylon: D3 has the DISKFREE-function, but it is
         only an integer!

radler: int64 is not defined in D3
the correct parameters for getdiskfreespaceex in D3 are:
LPCTSTR  name
freebytesavailable : integer
totalnumberofbytes : integer
totalnumberofbytesfree  : Pinteger
and only these types are supported.

what kind of extended do you mean ?

drdelphi: your large_integer-definition does not work
           because of compiler-error.

i think there will be no solution under D3 and WIN98.

but now we have carneval . therefore i will be back at tuesday or so.
have nice days !
titz

Commented:
Hi titz,

Are you Brazilian ?
I'm from Recife, at my opinion the best carneval from Brazil :-)
Extended ?
See what the Delphi docs from delphi tell me
Real48      2.9 x 10^–39 .. 1.7 x 10^38      11–12      6
Single      1.5 x 10^–45 .. 3.4 x 10^38      7–8      4
Double      5.0 x 10^–324 .. 1.7 x 10^308      15–16      8
Extended      3.6 x 10^–4951 .. 1.1 x 10^4932      19–20      10
Comp      –2^63+1 .. 2^63 –1      19–20      8
Currency      –922337203685477.5808.. 922337203685477.5807      19–20      8
You really ran my code ?

T++, Radler, and my return is tuesday too !

Commented:
hello,
I suggest you try that first, just create a new
program add a button.

the result is in bytes but you know that already.

and cut and paste the following unit.

///==========================

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    btnButton1: TButton;
    procedure btnButton1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function GetDiskFreeSpaceEx(lpDirectoryName: PAnsiChar;
   var lpFreeBytesAvailableToCaller : Integer;
   var lpTotalNumberOfBytes: Integer;
   var lpTotalNumberOfFreeBytes: Integer) : bool;
   stdcall;
   external kernel32
   name 'GetDiskFreeSpaceExA';


 procedure GetDiskSizeAvail(TheDrive : PChar;
                            var TotalBytes : double;
                            var TotalFree : double);
 var
   AvailToCall : integer;
   TheSize : integer;
   FreeAvail : integer;
 begin
   GetDiskFreeSpaceEx(TheDrive,
                      AvailToCall,
                      TheSize,
                      FreeAvail);
 {$IFOPT Q+}
  {$DEFINE TURNOVERFLOWON}
  {$Q-}
 {$ENDIF}
   if TheSize >= 0 then
     TotalBytes := TheSize else
   if TheSize = -1 then begin
     TotalBytes := $7FFFFFFF;
     TotalBytes := TotalBytes * 2;
     TotalBytes := TotalBytes + 1;
   end else
   begin
     TotalBytes := $7FFFFFFF;
     TotalBytes := TotalBytes + abs($7FFFFFFF - TheSize);
   end;

   if AvailToCall >= 0 then
     TotalFree := AvailToCall else
   if AvailToCall = -1 then begin
     TotalFree := $7FFFFFFF;
     TotalFree := TotalFree * 2;
     TotalFree := TotalFree + 1;
   end else
   begin
     TotalFree := $7FFFFFFF;
     TotalFree := TotalFree + abs($7FFFFFFF - AvailToCall);
   end;
 end;

procedure TForm1.btnButton1Click(Sender: TObject);
 var
   TotalBytes : double;
   TotalFree : double;
 begin
   GetDiskSizeAvail('C:\',
                    TotalBytes,
                    TotalFree);
   ShowMessage(FloatToStr(TotalBytes));
   ShowMessage(FloatToStr(TotalFree));
 end;

end.


CU.

Author

Commented:
hi Radler,
iam very sorry, but i am not brasilian. i am german, and we too have now carnaval. but i think you are right: i like the carnaval in brasil more than here.  
but the carnaval here is better than no carnaval !

i tried your code.
but i had compiler-problems: the error-message was, that the variable-types are not the right ones (sectorspercluser, ...:cardinal).
That was the problem. i think you have a newer version of delphi than i. because the definitions of real48 or int64 are not known in delphi.

hi jeurk,
i will try your suggestion tomorrow.
i will be back soon.
thanks,
titz

Author

Commented:
hi jeurk,

the values have nothing to do with reality.
Even sometimes the totalbytes is lower than totalfree.
i tried it on several large disks (4Gbyte to 8 Gbyte).
i do not understand some parts of your program:
i think that you gues that the values of
getdiskfreespaceex are correct but only negative.

cheers to all
titz
go to http://www.delphipages.com and have a look under System/API there is a freeware component that does API calls (like diskspace) easily. It's called TinyAPI I think, have a look it's on the 2nd last page of the System/API components page.

Andrew

Author

Commented:
hi andrew,

i did not find it under System/API.
can you give me the correct name, please ?

titz
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Commented:
Euh, 3 is for C: ;)

Author

Commented:
hi,

that is the solution !!!!

fantastic ! it works on all disks correct !
Many thanks !

titz

Commented:
You're welcome.
Remember that it will not work under 95
if you don't have osr2.x
And I think if your drive is a fat32 on the network it will not
work correctly either. But this is ms's fault.
CU
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.