#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; class CSimpleFileComponent { public: CSimpleFileComponent() :mftCreate(0) , mftModified(0) , mftAccess(0) , mAttributes(0) , mFileSize(0) , mLevel(-1) , mNameOffset(0) , mNameLength(0) { } //For CFileShell, the inherent class must re-implement the function. //as is: return new CInherentClass(*this); virtual CSimpleFileComponent* Clone() const { return new CSimpleFileComponent(*this); } virtual void Clear() { mftCreate = mftAccess = mftModified = 0; mAttributes = 0; mLevel = -1; mNameLength = 0; mNameOffset = 0; } public: ULONGLONG mftCreate; ULONGLONG mftModified; ULONGLONG mftAccess; ULONGLONG mFileSize; DWORD mAttributes; int mLevel; //file's hierarchy display in volume. DWORD mNameOffset; DWORD mNameLength; }; #if defined(_MSC_VER) static void GetTimeFormatStr(LPTSTR lpszString, DWORD dwSize, FILETIME* ftWrite) { SYSTEMTIME stUTC, stLocal; // Convert the last-write time to local time. FileTimeToSystemTime(ftWrite, &stUTC); SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); // Build a string showing the date and time. sprintf_s(lpszString, dwSize, "%02d/%02d/%d %02d:%02d:%02d", stLocal.wMonth, stLocal.wDay, stLocal.wYear, stLocal.wHour, stLocal.wMinute, stLocal.wSecond); return; } #else static void GetTimeFormatStr(LPTSTR lpszString, DWORD dwSize, const time_t* ftWrite) { tm* curTime = localtime(ftWrite); sprintf(lpszString, "%02d/%02d/%d %02d:%02d:%02d", (1 + curTime->tm_mon), curTime->tm_mday, (1900 + curTime->tm_year), curTime->tm_hour, curTime->tm_min, curTime->tm_sec); return; } #endif //_MSC_VER //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 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; } 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; } 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__