/* Determines the amount of free space available for the caller. Runs on Windows 95 retail and later, and on Windows 4.0 and later. Uses GetDiskFreeSpaceEx if available, otherwise reverts to GetDiskFreeSpace. To determine the amount of available space correctly: * Use 64-bit math with the return values of both GetDiskFreeSpace and GetDiskFreeSpaceEx so that you can determine the sizes of volumes that are larger than 2GB. Programs that need to determine how much free space the current user can have (such as whether there is enough space to complete an installation) have an additional requirement: * Use the lpFreeBytesAvailableToCaller value from GetDiskFreeSpaceEx rather than lpTotalNumberOfFreeBytes. This is because Windows 2000 has disk quota management that administrators may use to limit the amount of disk space that users may use. */ // Based on MSDN code // Modified for CVI by Guillaume Dargaud 30/10/99 #include #include #define E32 ((double)4294967296.) #define and && typedef BOOL (WINAPI *P_GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); // Emulates a 64 bits integer. Computations will actually be made on doubles. typedef struct int64s { unsigned long Low, High; } int64t; double AvailableDiskSize(char Drive) { BOOL fResult; char *pszDrive = "C:\\", szDrive[4]; DWORD dwSectPerClust, dwBytesPerSect, dwFreeClusters, dwTotalClusters; double FreeMegs, TotalMegs; P_GDFSE pGetDiskFreeSpaceEx = NULL; int64t i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes; Drive=toupper(Drive); if (Drive>=1 and Drive<=26) Drive+='A'-1; if (!(Drive>='A' and Drive<='Z')) return -1; szDrive[0]=Drive; szDrive[1]=':'; szDrive[2]='\\'; szDrive[3]='\0'; /* Use GetDiskFreeSpaceEx if available; otherwise, use GetDiskFreeSpace. Note: Since GetDiskFreeSpaceEx is not in Windows 95 Retail, we dynamically link to it and only call it if it is present. We don't need to call LoadLibrary on KERNEL32.DLL because it is already loaded into every Win32 process's address space. */ pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress ( GetModuleHandle ("kernel32.dll"), "GetDiskFreeSpaceExA"); if (pGetDiskFreeSpaceEx) { fResult = pGetDiskFreeSpaceEx (pszDrive, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes, (PULARGE_INTEGER)&i64FreeBytes); if (fResult) { // printf ("\n\nGetDiskFreeSpaceEx reports\n\n"); // printf ("Available space to caller = %f Mb\n", // ((double)i64FreeBytesToCaller.High*E32 + i64FreeBytesToCaller.Low)/(1024*1024)); // printf ("Total space = %f Mb\n", // ((double)i64TotalBytes.High*E32 + i64TotalBytes.Low)/(1024*1024)); // printf ("Free space on drive = %f Mb\n", // ((double)i64FreeBytes.High*E32 + i64FreeBytes.Low)/(1024*1024)); return ((double)i64FreeBytesToCaller.High*E32 + i64FreeBytesToCaller.Low)/(1024*1024); } } else { fResult = GetDiskFreeSpace (pszDrive, &dwSectPerClust, &dwBytesPerSect, &dwFreeClusters, &dwTotalClusters); if (fResult) { /* force 64-bit math */ TotalMegs = (double)dwTotalClusters * dwSectPerClust * dwBytesPerSect / (1024*1024); return FreeMegs = (double)dwFreeClusters * dwSectPerClust * dwBytesPerSect / (1024*1024); // printf ("GetDiskFreeSpace reports\n\n"); // printf ("Free space = %I64u MB\n", FreeMegs); // printf ("Total space = %I64u MB\n", TotalMegs); } } if (!fResult) // printf ("error: %lu: could not get free space for \"%s\"\n", // GetLastError(), argv[1]) ; return 0; } void main (void) { printf("\nAvailable size on drive C: %fMb", AvailableDiskSize('C')); }