#ifndef _RESOURCE_FILEINFO_H__ #define _RESOURCE_FILEINFO_H__ #pragma once #include "stdafx.h" #include "SpFSM.h" #ifndef _WIN32 #include #include #endif //NOT _WIN32 #ifndef MAX_PATH #define MAX_PATH 1024 #endif #ifndef ULONGLONG_ERROR #if defined(_MSC_VER) #define ULONGLONG_ERROR (0xffffffffffffffffui64) #else #define ULONGLONG_ERROR ((unsigned long long)(-1)) #endif //_MSC_VER #endif #ifndef ULONGLONG_MAX #if defined(_MSC_VER) #define ULONGLONG_MAX (0xffffffffffffffffui64) #else #define ULONGLONG_MAX ((unsigned long long)(-1)) #endif //_MSC_VER #endif #define DEFAULT_VIDEOFILE_CREATE_COUNT 1 #define DEFAULT_AVAILALBE_DATE_COUNT 7 #define LESS_AVAILALBE_DATE_COUNT 3 #define LEAST_AVAILALBE_DATE_COUNT 1 #define BASE_AVAILALBE_DATE_COUNT 1 #define DEFAULT_SAVE_DATE_COUNT 14 #define DEFAULT_OUTPUT_FORMAT_SIZE 128 /* labels for Byte formats [KMG] */ static const char* kLabel_Byte[] = { "Byte", "KByte", "MByte", "GByte", "TByte" }; const double kConversion[] = { 1.0, /* unit */ 1.0 / 1024, /* Kilo */ 1.0 / 1024 / 1024, /* Mega */ 1.0 / 1024 / 1024 / 1024, /* Giga */ 1.0 / 1024 / 1024 / 1024 / 1024 /* Tera */ }; enum { kConv_Unit, kConv_Kilo, kConv_Mega, kConv_Giga, kConv_Tera }; const long kKilo_to_Unit = 1024; const long kMega_to_Unit = 1024 * 1024; const long kGiga_to_Unit = 1024 * 1024 * 1024; //const long kTera_to_Unit = 1024 * 1024 * 1024 * 1024; #include #include #include using namespace std; //OutString must be [DEFAULT_OUTPUT_FORMAT_SIZE] size. static void ByteSprintf(char * outString, double inNum, char inFormat = 'A') { memset(outString, 0, sizeof(char)*DEFAULT_OUTPUT_FORMAT_SIZE); int conv; const char* suffix; const char* format; switch(toupper(inFormat)) { case 'B': conv = kConv_Unit; break; case 'K': conv = kConv_Kilo; break; case 'M': conv = kConv_Mega; break; case 'G': conv = kConv_Giga; break; default: case 'A': { double tmpNum = inNum; conv = kConv_Unit; while(tmpNum >= 1024.0 && conv <= kConv_Tera){ tmpNum /= 1024.0; if(conv == kConv_Giga) break; conv++; } break; } } inNum *= kConversion[conv]; suffix = kLabel_Byte[conv]; if(inNum < 9.995) { format = "%4.2f %s"; } else if (inNum < 99.95) { format = "%4.1f %s"; } else if(inNum < 999.5) { format = "%4.0f %s"; } else { format = "%4.0f %s"; } #if defined(_MSC_VER) _snprintf_s(outString, DEFAULT_OUTPUT_FORMAT_SIZE, DEFAULT_OUTPUT_FORMAT_SIZE, format, inNum, suffix); #else snprintf(outString, DEFAULT_OUTPUT_FORMAT_SIZE, format, inNum, suffix); #endif //_MSC_VER } static void PrintDiskStatus(LPCTSTR dir, const unsigned long long& uiDiskFreeSize, const unsigned long long& uiDiskOverallSize) { char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; char szResult2[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)uiDiskFreeSize); ByteSprintf(szResult2, (double)uiDiskOverallSize); double dFreeRate = (uiDiskFreeSize * kConversion[3]) / (uiDiskOverallSize * kConversion[3]); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[Disk(%s)] total: %s, free: %s, rate: %.1lf%%.", dir, szResult2, szResult, dFreeRate * 100); } struct TmpFileInfo { #if defined(_MSC_VER) string msFileName; FILETIME mftEditTime; DWORD mDwFileSizeHeight; DWORD mDwFileSizeLow; TmpFileInfo(LPCTSTR lpszFileName, const PFILETIME ftEditTime, DWORD dwFileSizeHeight, DWORD dwFileSizeLow) : msFileName(lpszFileName) , mftEditTime(*ftEditTime) , mDwFileSizeHeight(dwFileSizeHeight) , mDwFileSizeLow(dwFileSizeLow) { } #else string msFileName; time_t mftEditTime; off_t ftSize; TmpFileInfo() :msFileName(""), mftEditTime(0), ftSize(0){} TmpFileInfo(LPCTSTR lpszFileName, const time_t ftEditTime, off_t fileSize) : msFileName(lpszFileName) , mftEditTime(ftEditTime) , ftSize(fileSize) { } ~TmpFileInfo() {} #endif //_MSC_VER }; struct Comparetor { bool operator () (const TmpFileInfo* lhs, const TmpFileInfo* rhs) const { #if defined(_MSC_VER) if (CompareFileTime(&(lhs->mftEditTime), &(rhs->mftEditTime)) > 0) return true; return false; #else return (lhs->mftEditTime > rhs->mftEditTime); #endif //_MSC_VER } }; struct DiskInfo { #if defined(_MSC_VER) //录像文件所在磁盘的空间大小(Bytes) ULARGE_INTEGER mUliDiskOverallSize; //录像文件夹所在磁盘的剩余空间大小(Bytes) ULARGE_INTEGER mUliDiskFreeSize; //录像文件夹的大小(Bytes) ULARGE_INTEGER mUiAllVideoFilesBytes; //录像文件数量 UINT mUVideoFileCount; //未上传录像文件夹的大小(Bytes) ULARGE_INTEGER mUiUploadVideoFileBytes; //录像文件生成的有效天数 UINT mUVideoCreateDayCount; BOOL mBAverageAvailable; //平均录像文件的大小(Bytes) ULARGE_INTEGER mUliAverageFileSize; //平均每天录像的数目(当天无录像的不考虑) UINT mUAverageFileCreated; //需预留的磁盘空间大小(Bytes) ULARGE_INTEGER mUiFreeBytesRequired; //当前最大的录像文件 ULARGE_INTEGER mUiMaxFileSize; #else unsigned long long mUliDiskOverallSize; unsigned long long mUliDiskFreeSize; unsigned long long mUiAllVideoFilesBytes; unsigned int mUVideoFileCount; unsigned long long mUiUploadVideoFileBytes; unsigned int mUVideoCreateDayCount; int mBAverageAvailable; unsigned long long mUliAverageFileSize; unsigned int mUAverageFileCreated; unsigned long long mUiFreeBytesRequired; unsigned long long mUiMaxFileSize; #endif //_MSC_VER DiskInfo() : mUVideoFileCount(0) , mUVideoCreateDayCount(0) , mBAverageAvailable(FALSE) , mUAverageFileCreated(0) { #if defined(_MSC_VER) mUliDiskOverallSize.QuadPart = 0; mUliDiskFreeSize.QuadPart = 0; mUiAllVideoFilesBytes.QuadPart = 0; mUliAverageFileSize.QuadPart = 0; mUiUploadVideoFileBytes.QuadPart = ULONGLONG_ERROR; mUiFreeBytesRequired.QuadPart = 0; mUiMaxFileSize.QuadPart = 0; #else mUliDiskOverallSize = 0; mUliDiskFreeSize = 0; mUiAllVideoFilesBytes = 0; mUliAverageFileSize = 0; mUiUploadVideoFileBytes = 0; mUiFreeBytesRequired = 0; mUiMaxFileSize = 0; #endif //_MSC_VER } BOOL Initial(LPCTSTR lpszVideoPath) { if(lpszVideoPath == NULL || strlen(lpszVideoPath) == 0) return FALSE; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("当前录像文件夹所在的磁盘: %c", lpszVideoPath[0]); #if defined(_MSC_VER) BOOL bRet = GetDiskSpace(lpszVideoPath, mUliDiskOverallSize, mUliDiskFreeSize); if (bRet) { char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)mUliDiskOverallSize.QuadPart); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("录像文件所在磁盘的空间大小 : %s", szResult); ByteSprintf(szResult, (double)mUliDiskFreeSize.QuadPart); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("录像文件夹所在磁盘的剩余空间大小 : %s", szResult); } return bRet; #else BOOL bRet = GetDiskSpace(lpszVideoPath, mUliDiskOverallSize, mUliDiskFreeSize); if (bRet) { char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)mUliDiskOverallSize); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("录像文件所在磁盘的空间大小 : %s", szResult); ByteSprintf(szResult, (double)mUliDiskFreeSize); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("录像文件夹所在磁盘的剩余空间大小 : %s", szResult); } return bRet; #endif //_MSC_VER } #if defined(_MSC_VER) void SetUploadVideoDirSize(ULARGE_INTEGER uiRhs) { mUiUploadVideoFileBytes = uiRhs; } void SetMaxVideoFileSize(ULARGE_INTEGER uiRhs) { mUiMaxFileSize = uiRhs; } BOOL CalAverRequreSpaceEachDay( const ULARGE_INTEGER& uiAllVideoFileBytes, const UINT uVideoFileCount, const UINT uAvailDayCount, const UINT uRequredDays, ULARGE_INTEGER& uiRequireBytes) { mUiAllVideoFilesBytes = uiAllVideoFileBytes; mUVideoFileCount = uVideoFileCount; mUVideoCreateDayCount = uAvailDayCount; char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)mUiAllVideoFilesBytes.QuadPart); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("录像文件夹的大小 : %s", szResult); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("已上传录像文件数量 : %u", mUVideoFileCount); //平均每天的录像数目 mUAverageFileCreated = DEFAULT_VIDEOFILE_CREATE_COUNT; if (mUVideoCreateDayCount != 0) { mUAverageFileCreated = mUVideoFileCount / mUVideoCreateDayCount; } //平均录像文件的大小 TODO: mUliAverageFileSize = mUiAllVideoFilesBytes; if (mUVideoFileCount != 0) { mUliAverageFileSize.QuadPart = mUiAllVideoFilesBytes.QuadPart / mUVideoFileCount; } ByteSprintf(szResult, (double)mUliAverageFileSize.QuadPart); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("平均录像文件的大小 : %s", szResult); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("平均每天录像的数目 : %u", mUAverageFileCreated); //预估每天需要提供的空间大小 ULARGE_INTEGER uiForecastDailySpace; uiForecastDailySpace.QuadPart = mUliAverageFileSize.QuadPart * mUAverageFileCreated; //至少需预留的磁盘空间大小 ULARGE_INTEGER uiForecastSpaceAvail; uiForecastSpaceAvail.QuadPart = uiForecastDailySpace.QuadPart * uRequredDays; ByteSprintf(szResult, (double)uiForecastSpaceAvail.QuadPart); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("需预留的磁盘空间大小 : %s", szResult); mUiFreeBytesRequired = uiForecastSpaceAvail; uiRequireBytes = uiForecastSpaceAvail; return (mBAverageAvailable = TRUE); } BOOL IsNeedToDoClearJobEx(LPCTSTR lpszDiskPath, const ULARGE_INTEGER& uiRequiredByts, const ULARGE_INTEGER& uiAdjustmentFactor, PULARGE_INTEGER pUiRealRequiredByts) { BOOL bRet = FALSE; if (lpszDiskPath == NULL || strlen(lpszDiskPath) == 0) return FALSE; if (pUiRealRequiredByts != NULL) { pUiRealRequiredByts->QuadPart = 0; } ULARGE_INTEGER uiDiskOverallSize; ULARGE_INTEGER uiDiskFreeSize; bRet = GetDiskSpace(lpszDiskPath, uiDiskOverallSize, uiDiskFreeSize); if (bRet) { assert(uiDiskOverallSize.QuadPart != 0); char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; char szResult2[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)uiDiskFreeSize.QuadPart); ByteSprintf(szResult2, (double)uiDiskOverallSize.QuadPart); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Current operated disk(%s) : %s / %s", lpszDiskPath, szResult, szResult2); ULARGE_INTEGER uiForecastSpaceAvail; uiForecastSpaceAvail.QuadPart = uiRequiredByts.QuadPart + uiAdjustmentFactor.QuadPart; if (uiForecastSpaceAvail.QuadPart > uiDiskFreeSize.QuadPart) { ULARGE_INTEGER uiTemp; uiTemp.QuadPart = uiForecastSpaceAvail.QuadPart - uiDiskFreeSize.QuadPart; ByteSprintf(szResult, (double)uiTemp.QuadPart); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("More space required : %s", szResult); if (pUiRealRequiredByts != NULL) { pUiRealRequiredByts->QuadPart = uiTemp.QuadPart; } } } return bRet; } BOOL IsNeedToDoClearJob(const ULARGE_INTEGER& uiAdjustmentFactor, PULARGE_INTEGER pUiRealRequiredByts) { BOOL bResult = FALSE; char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; //ByteSprintf(szResult, ULONGLONG_ERROR); if (mUiUploadVideoFileBytes.QuadPart != ULONGLONG_ERROR) { ByteSprintf(szResult, (double)mUiUploadVideoFileBytes.QuadPart); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("未上传录像文件夹的大小 : %s", szResult); } #if JUS_A_TEST //uiAdjustmentFactor.QuadPart = 1024ui64 * 1024 * 1024 * 100 * 4; #endif if (pUiRealRequiredByts != NULL) { pUiRealRequiredByts->QuadPart = 0; } ULARGE_INTEGER uiForecastSpaceAvail; if (!mBAverageAvailable) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("mBAverageAvailable == FALSE"); return FALSE; } uiForecastSpaceAvail.QuadPart = mUiFreeBytesRequired.QuadPart + uiAdjustmentFactor.QuadPart; assert(mUliDiskOverallSize.QuadPart != 0); if (uiForecastSpaceAvail.QuadPart > mUliDiskFreeSize.QuadPart) { //TODO: Alert !! ULARGE_INTEGER uiTemp; uiTemp.QuadPart = uiForecastSpaceAvail.QuadPart - mUliDiskFreeSize.QuadPart; ByteSprintf(szResult, (double)uiTemp.QuadPart); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("需要待清理的空间大小 : %s", szResult); if (pUiRealRequiredByts != NULL) { pUiRealRequiredByts->QuadPart = uiTemp.QuadPart; } bResult = TRUE; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("当前无需对磁盘空间进行清理。"); } return bResult; } static BOOL GetDiskSpace( LPCTSTR lpszVideoPath, ULARGE_INTEGER& uiTotalByteNumber, ULARGE_INTEGER& uiTotalFreeByteNumber) { if (lpszVideoPath == NULL || strlen(lpszVideoPath) == 0) return FALSE; ULARGE_INTEGER uiFreeBytesAvailable; ULARGE_INTEGER uiTotalNumberOfBytes; ULARGE_INTEGER uiTotalNumberOfFreeBytes; char szDisk[MAX_PATH] = { 0 }; sprintf_s(szDisk, "%c:", lpszVideoPath[0]); BOOL bRet = GetDiskFreeSpaceExA(szDisk, &uiFreeBytesAvailable, &uiTotalNumberOfBytes, &uiTotalNumberOfFreeBytes); if (!bRet) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetDiskFreeSpaceEx(%s) failed, GLE=%u", szDisk, GetLastError()); return FALSE; } uiTotalByteNumber = uiTotalNumberOfBytes; uiTotalFreeByteNumber = uiTotalNumberOfFreeBytes; return bRet; } #else void SetUploadVideoDirSize(unsigned long long uiRhs) { mUiUploadVideoFileBytes = uiRhs; } void SetMaxVideoFileSize(unsigned long long uiRhs) { mUiMaxFileSize = uiRhs; } BOOL CalAverRequreSpaceEachDay( const unsigned long long& uiAllVideoFileBytes, const unsigned int uVideoFileCount, const unsigned int uAvailDayCount, const unsigned int uRequredDays, unsigned long long& uiRequireBytes) { mUiAllVideoFilesBytes = uiAllVideoFileBytes; mUVideoFileCount = uVideoFileCount; mUVideoCreateDayCount = uAvailDayCount; char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)mUiAllVideoFilesBytes); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("录像文件夹的大小 : %s", szResult); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("录像文件数量(已上传+未上传) : %u", mUVideoFileCount); //平均每天的录像数目 mUAverageFileCreated = DEFAULT_VIDEOFILE_CREATE_COUNT; if (mUVideoCreateDayCount != 0) { mUAverageFileCreated = mUVideoFileCount / mUVideoCreateDayCount; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("平均每天录像的数目 : %u", mUAverageFileCreated); //平均录像文件的大小 TODO: if (mUVideoFileCount != 0) { mUliAverageFileSize = mUiAllVideoFilesBytes / mUVideoFileCount; } else { mUliAverageFileSize = mUiAllVideoFilesBytes; } ByteSprintf(szResult, (double)mUliAverageFileSize); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("平均录像文件的大小 : %s", szResult); //预估每天需要提供的空间大小 = 平均每个文件大小 * 平均每天文件数量 const unsigned long long uiForecastDailySpace = mUliAverageFileSize * mUAverageFileCreated; //至少需预留的磁盘空间大小 = 平均每天需要的大小*要求留存的天数 const unsigned long long uiForecastSpaceAvail = uiForecastDailySpace * uRequredDays; ByteSprintf(szResult, (double)uiForecastSpaceAvail); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("需预留的磁盘空间大小(平均每个文件大小 * 平均每天文件数量 * 要求留存的天数#%u) : %s", uRequredDays, szResult); mUiFreeBytesRequired = uiForecastSpaceAvail; uiRequireBytes = uiForecastSpaceAvail; return (mBAverageAvailable = TRUE); } /** uiAdjustmentFactor: 增量调整因子 */ BOOL IsNeedToDoClearJobEx(LPCTSTR lpszDiskPath, const unsigned long long& uiRequiredByts, const unsigned long long& uiAdjustmentFactor, unsigned long long* pUiRealRequiredByts) { BOOL bRet = FALSE; if (lpszDiskPath == NULL || strlen(lpszDiskPath) == 0) return FALSE; if (pUiRealRequiredByts != NULL) { *pUiRealRequiredByts = 0; } unsigned long long uiDiskOverallSize; unsigned long long uiDiskFreeSize; bRet = GetDiskSpace(lpszDiskPath, uiDiskOverallSize, uiDiskFreeSize); if (bRet) { assert(uiDiskOverallSize != 0); PrintDiskStatus(lpszDiskPath, uiDiskFreeSize, uiDiskOverallSize); const unsigned long long uiForecastSpaceAvail = uiRequiredByts + uiAdjustmentFactor; if (uiForecastSpaceAvail > uiDiskFreeSize) { unsigned long long uiTemp; uiTemp = uiForecastSpaceAvail - uiDiskFreeSize; char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)uiTemp); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("More space required : %s", szResult); if (pUiRealRequiredByts != NULL) { *pUiRealRequiredByts = uiTemp; } return TRUE; } } return FALSE; } BOOL IsNeedToDoClearJob(const unsigned long long& uiAdjustmentFactor, unsigned long long* pUiRealRequiredByts) { BOOL bResult = FALSE; char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; if (mUiUploadVideoFileBytes != ULONGLONG_ERROR) { ByteSprintf(szResult, (double)mUiUploadVideoFileBytes); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("未上传录像文件夹的大小 : %s", szResult); } if (pUiRealRequiredByts != NULL) { *pUiRealRequiredByts = 0; } unsigned long long uiForecastSpaceAvail; if (!mBAverageAvailable) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("mBAverageAvailable == FALSE"); return FALSE; } uiForecastSpaceAvail = mUiFreeBytesRequired + uiAdjustmentFactor; assert(mUliDiskOverallSize != 0); if (uiForecastSpaceAvail > mUliDiskFreeSize) { //TODO: Alert !! unsigned long long uiTemp; uiTemp = uiForecastSpaceAvail - mUliDiskFreeSize; ByteSprintf(szResult, (double)uiTemp); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("需要待清理的空间大小 : %s", szResult); if (pUiRealRequiredByts != NULL) { *pUiRealRequiredByts = uiTemp; } bResult = TRUE; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("当前无需对磁盘空间进行清理。"); } return bResult; } static BOOL GetDiskSpace(LPCTSTR lpszVideoPath,unsigned long long& uiTotalByteNumber, unsigned long long& uiTotalFreeByteNumber) { struct statfs buf; int result = statfs(lpszVideoPath, &buf); if (result < 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("statfs failed: %d", errno); return FALSE; } /** statfs结构中可用空间块数有两种f_bfree和 f_bavail,前者是硬盘所有剩余空间,后者为非root用户剩余空间, ext3文件系统给root用户分有5%的独享空间,所以这里是不同的地方 */ //uiTotalByteNumber = (((long long)buf.f_bsize * (long long)buf.f_blocks)); //uiTotalFreeByteNumber = (((long long)buf.f_bsize * (long long)buf.f_bfree)); const int percent = (buf.f_blocks - buf.f_bfree) * 100 / (buf.f_blocks - buf.f_bfree + buf.f_bavail); uiTotalByteNumber = (((long long)buf.f_bsize * (long long)(buf.f_blocks - buf.f_bfree + buf.f_bavail))); uiTotalFreeByteNumber = (((long long)buf.f_bsize * (long long)buf.f_bavail)); return TRUE; } #endif //_MSC_VER }; #endif //_RESOURCE_FILEINFO_H__