- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am attempting to get the disc free space available for a user with the following:
INTEGER(4) iret
INTEGER(8), TARGET :: iFB
INTEGER(8), POINTER :: pFB
TYPE(T_LARGE_INTEGER) iFreeBytes
pFB => iFB
iret = GetDiscFreeSpaceEX('H:'C, iFreeBytes,
NULL, NULL)
! because 8 bytes are contiguous in memory
pFB = LOC(iFreeBytes)
From Exporer I know thedisc has about 129GBs of free disc space, however, when I execute the code above iFB shows only about 5MBs of free space.
Is the use ofthe pointer pFB correct in the code above?
I also noticed that the sign bit was set for the LowPart whichalso appears to be a problem:
iFreeBytes%LowPart = -1525272576
iFreeBytes%HighPart = 3
Any comments would be appreciated. Thanks in advance.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This version works. I use Compaq Visual Fortran 6.6C, but you should be able to see what changes to make for IVF. Note I cannot do 64-bit integer arithmetic, so I converted to REAL arithmetic and did the sums andI checked the values it gave me doing the sum indicated against values given by Explorer and they were identical. Note the double back-slash needeed for the folder C-string and I had to use GetDisKFreeSpace with a 'K' in DisK rather than a 'C'.
program freespace
use kernel32
use dfwin
implicit none
REAL(8) Callerbytes, Threadbytes, Totalbytes, Factor
INTEGER(4) iret
TYPE(T_LARGE_INTEGER) iCallerBytes, iThreadBytes, iTotalBytes
character(10) Folder
folder='C:'C
iret = GetDiskFreeSpaceEx(folder, iCallerBytes, iThreadBytes, iTotalBytes)
print *,' IF LOWPART is >0, Total bytes = 2**32 x HIGHPART + LOWPART'
print *,' IF LOWPART is <0, Total bytes = 2**32 x (HIGHPART+1) + LOWPART'
print *
print *,' HIGHPART LOWPART'
print *,'bytes free to Caller = ',iCallerbytes%highpart,' ', icallerbytes%lowpart
print *,'bytes free to Thread = ',iThreadbytes%highpart,' ', iThreadbytes%lowpart
print *,'bytes free Total = ',iTotalbytes%highpart, ' ',iTotalbytes%lowpart
factor=2.0d+00**32
if(icallerbytes%lowpart<0) then
Callerbytes=factor*(dble(iCallerbytes%highpart+1))+dble(icallerbytes%lowpart)
else
Callerbytes=factor*(dble(iCallerbytes%highpart))+dble(icallerbytes%lowpart)
endif
if(ithreadbytes%lowpart<0) then
threadbytes=factor*(dble(ithreadbytes%highpart+1))+dble(ithreadbytes%lowpart)
else
threadbytes=factor*(dble(ithreadbytes%highpart))+dble(ithreadbytes%lowpart)
endif
if(itotalbytes%lowpart<0) then
totalbytes=factor*(dble(itotalbytes%highpart+1))+dble(itotalbytes%lowpart)
else
totalbytes=factor*(dble(itotalbytes%highpart))+dble(itotalbytes%lowpart)
endif
print *,'bytes free to Caller = ',Callerbytes
print *,'bytes free to Thread = ',Threadbytes
print *,'bytes free Total = ',Totalbytes
end program freespace
OUTPUT FOLLOWS:
IF LOWPART is >0, Total bytes = 2**32 x HIGHPART + LOWPART
IF LOWPART is <0, Total bytes = 2**32 x (HIGHPART+1) + LOWPART
HIGHPART LOWPART
bytes free to Caller = 5 1557180416
bytes free to Thread = 9 -1000779776
bytes free Total =&nbs p; 5 1557180416
bytes free to Caller = 23032016896.0000
bytes free to Thread = 41948893184.0000
bytes free Total = 23032016896.0000
Press any key to continue
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is an sample program which might be easier to use. I simply copied the INTERFACE from KERNEL32.f90 and changed those ULONGLONG args into INTEGER*8. So you don't have to considerthose sign bits.
Joerg Kuthe
www.qtsoftware.de
PROGRAM
T_GetDiskFreeSpaceExUSE IFWINTYUSE KERNEL32IMPLICIT NONEINTEGER :: iRetINTEGER(8) lpFreeBytesAvailableToCaller ! PULARGE_INTEGER lpFreeBytesAvailableToCallerINTEGER(8) lpTotalNumberOfBytes ! PULARGE_INTEGER lpTotalNumberOfBytesINTEGER(8) lpTotalNumberOfFreeBytes ! PULARGE_INTEGER lpTotalNumberOfFreeBytesCHARACTER(*), PARAMETER :: szDir = 'C:'CINTERFACEFUNCTION qtGetDiskFreeSpaceEx( lpDirectoryName, lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes)use ifwintyinteger(BOOL) :: qtGetDiskFreeSpaceEx ! BOOL!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'GetDiskFreeSpaceExA' :: qtGetDiskFreeSpaceEx!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpDirectoryNameCHARACTER*(*) lpDirectoryName!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpFreeBytesAvailableToCallerINTEGER(8) lpFreeBytesAvailableToCaller ! PULARGE_INTEGER lpFreeBytesAvailableToCaller!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpTotalNumberOfBytesINTEGER(8) lpTotalNumberOfBytes ! PULARGE_INTEGER lpTotalNumberOfBytes!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpTotalNumberOfFreeBytesINTEGER(8) lpTotalNumberOfFreeBytes ! PULARGE_INTEGER lpTotalNumberOfFreeBytesEND FUNCTIONEND INTERFACEiRet = qtGetDiskFreeSpaceEx( szDir, lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, &
lpTotalNumberOfFreeBytes )
IF ( iRet /= 0 ) THEN
WRITE(*,6000) szDir(1:3)6000 FORMAT('Size of Directory "', A '"')CALL CS_PrintResult( 'Free Bytes Available To Caller', lpFreeBytesAvailableToCaller )CALL CS_PrintResult( 'Total Number Of Bytes', lpTotalNumberOfBytes )CALL CS_PrintResult( 'Total Number Of Free Bytes', lpTotalNumberOfFreeBytes )ELSEPRINT*,'GetDiskFreeSpaceEx() failed; error = ', GetLastError()END IFCONTAINS
SUBROUTINE CS_PrintResult( cText, i8MemVal )CHARACTER(*), INTENT(IN) :: cTextINTEGER(8), INTENT(IN) :: i8MemValWRITE(*,6000) TRIM(cText), i8MemVal, i8MemVal / (1024.*1024.)6000 FORMAT(A, ' = ', I0, ' (= ', F0.3, ' MB)')END SUBROUTINE CS_PrintResultEND
PROGRAM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for both replies. I was stumped for a little while about the math used inanthonyrichardsexample code, but after a littlebinary math realized that Fortran displays the two's compliment +1 of the binary when the sign bit is set.A little binary math demonstrated thatadding 1 to theHighPart and multiplying by factorand then adding the negative LowPart actuallyproduces the correct result.
In the second example,I realize that the HighPart and LowPart of the structure Large_Integer (filled in by the Win32 fn.) are contiguous in memory, and thatSTDCALL means that actual values are returned in the Win32 function arg list.However, not clear on how returning actual values for a C structure works in an arg list. Sincecode works fine, I assume that the arg or returned values for theC structure will always be just 8 contiguous Bytes. Is there anyrisk that manipulating the INTERFACE in this way may cause unexpected problems?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
All arguments in the
FUNCTION qtGetDiskFreeSpaceEx( lpDirectoryName, lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes)
are returned by REFERENCE (STDCALL passes arguments by VALUE, so you have to change the interface). This means, not the value itself is returned but the starting address of memory where the values of
lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes
are found. The type information then specifies how many bytes have to be considered to obtain thevalue.So you can handle any size of argument.
I don't see a risk in the kind of manipulation that I have made because I simply gave those 8-bytes being addressed just another type of the same memory sizeas expected(INTEGER(8)).
It is your decision how you want your compiler to handle those arguments. So you choose what suits your needs best.
Joerg Kuthe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks forthe explanation about how memory was treated.
I was fixated on the ATTRIBUTES STDCALL for qtGetDiskFreeSpaceEX(),but now seethat the ATTRIBUTES REFERENCEyou gave to the arguments overrides pass by value.
Trying to learnabout INTERFACE Blocks, and your example helped quite a bit.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page