#include "stdafx.h" #include "ResourceWatcherFSM.h" #include "DeviceBaseClass.h" #include "publicFunExport.h" #include #include #include #include #include #if defined(RVC_OS_WIN) #include #include #include #include "shellapi.h" #include "Mmdeviceapi.h" #include "Propidl.h" #include "Functiondiscoverykeys_devpkey.h" #include "PolicyConfig.h" #endif //RVC_OS_WIN #include #include #include "toolkit.h" #include "fileutil.h" #include "iniutil.h" #include "osutil.h" #include "CommEntityUtil.hpp" #include "SpUtility.h" //#include "NetworkProbe.h" #include "RestfulFunc.h" //硬件信息搜集参数 const int MAX_HARDWARE_CHECK_TIME = 5000; const int TIMER_HARDWARE_CHECK = 2; const int MAX_MAINLINK_CHECK_TIME = 5000; const int TIMER_MAINLINK_CHECK = 4; const int DEFAULT_DAY_OF_BACKWARD = 90; const int MAX_DAY_OF_BACKWARD = 365; const char* DEFAULT_DELETE_FILE_SUFFIX = "*"; LPCTSTR UPLOAD_VIDEO_PATH = "UploadVideo"; const int AD0_DAY_OF_BACKWARD = 7; const int TIMER_INTERVAL_CLEARVIDEO_ENHANCE = 60 * 1000; const int MAX_VERSION_PATH = 256; //保留版本数目 const int DEFAULT_VERSION_SAVED_COUNT = 2; CRITICAL_SECTION g_csVideoMoreClear; #define MAX_VOLUME_COUNT 26 #define BUFSIZE 512 static BOOL sBDiskValStatus[MAX_VOLUME_COUNT + 1] = { FALSE }; #define MAX_SUBFILES_COUNT 1000 #define DIV (1024 * 1024) #define DAY_DIV (24 * 60 * 60) #define HOURS_DIV (60 * 60) #define MINUS_DIV (60) const char* SystemElapsedQuery = "\\System\\System Up Time"; template class TimerOutHelper : public ITimerListener { public: typedef void (T::* FuncTimer)(void* pUserdata); TimerOutHelper(T* p, FuncTimer pTimerFunc, void* pData, bool bDeleteSelf = false) : m_pObject(p), m_pUserData(pData), m_pTimer(pTimerFunc), m_bDeleteSelf(bDeleteSelf) { } virtual void OnTimeout(DWORD dwTimerID) { (m_pObject->*m_pTimer)(m_pUserData); if (m_bDeleteSelf) delete this; } private: void* m_pUserData; T* m_pObject; FuncTimer m_pTimer; bool m_bDeleteSelf; }; ResourceWatcherFSM::ResourceWatcherFSM(void) :m_IsPadDevice(FALSE) , m_bGetStatusRotate(FALSE) , m_uploadedVideoDirPath(true) , m_csDelFileSuffix(true) , m_nDayOfBackward(DEFAULT_DAY_OF_BACKWARD) , m_failDelCnt(0) , m_bReadyFlag(false) , m_bVideoClearReady(false) , m_nMinSavedDay(DEFAULT_SAVE_DATE_COUNT) , m_highPart(0) , m_lowPart(0) , m_strTerminalNo(true) , m_strDefaultDns(true) , m_strBackupDns(true) , m_nEnableSetDns(0) , m_bFirstRunAfterBoot(FALSE) , m_bIsConfigMode(FALSE) { #if defined(_MSC_VER) mUiRequireBytes.QuadPart = 0; mUiCalibration.QuadPart = 0; #else mAllVideoFileSizeCal = 0; mMaxFileSize = 0; mUiCalibration = 0; mUiRequireBytes = 0; mftAd0RemoveTime = 0; #endif //_MSC_VER } ResourceWatcherFSM::~ResourceWatcherFSM(void) { } void ResourceWatcherFSM::ClearVideoQueue() { while (!m_VideoFiles.empty()) { TmpFileInfo* pNodeInfo = m_VideoFiles.top(); m_VideoFiles.pop(); if (pNodeInfo != NULL) { delete pNodeInfo; } } memset(szMaxSizeFilePath, 0, sizeof(szMaxSizeFilePath)); #if defined(_MSC_VER) mAllVideoFileSizeCal.QuadPart = 0ui64; mMaxFileSize.QuadPart = 0ui64; mUiRequireBytes.QuadPart = 0ui64; #else mAllVideoFileSizeCal = 0; mMaxFileSize = 0; mUiRequireBytes = 0; #endif //_MSC_VER VideoDailyRecord.clear(); } void ResourceWatcherFSM::PrintVideEmurateResult() { char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; #if defined(_MSC_VER) ByteSprintf(szResult, (double)mMaxFileSize.QuadPart); Dbg("Max Video file: %s size: %s", szMaxSizeFilePath, szResult); Dbg("mAllVideoFileSizeCal.QuadPart : %I64u Bytes", mAllVideoFileSizeCal.QuadPart); ByteSprintf(szResult, (double)mAllVideoFileSizeCal.QuadPart); #else ByteSprintf(szResult, (double)mMaxFileSize); Dbg("Max Video file: %s size: %s", szMaxSizeFilePath, szResult); Dbg("mAllVideoFileSizeCal : %llu Bytes", mAllVideoFileSizeCal); ByteSprintf(szResult, (double)mAllVideoFileSizeCal); #endif //_MSC_VER Dbg("Totally(size: %d) directory size: %s", m_VideoFiles.size(), szResult); } void ResourceWatcherFSM::s0_on_entry() { LOG_FUNCTION(); if (!m_bIsConfigMode) { this->PostEventFIFO(new RunEvent()); GetCpuType(NULL); } else { Dbg("in config mode, do nothing about clear job"); } } unsigned int ResourceWatcherFSM::s0_on_event(FSMEvent* e) { LOG_FUNCTION(); unsigned int unRes = 0; switch (e->iEvt) { case USER_EVT_RUN: { if (m_IsPadDevice) { GetCardSwiperTask* task = new GetCardSwiperTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } #if 0 ClearVideoFilesTask* videoTask = new ClearVideoFilesTask(this); videoTask->SetFlag(m_bReadyFlag ? 1 : 0); GetEntityBase()->GetFunction()->PostThreadPoolTask(videoTask); GetEntityBase()->GetFunction()->PostThreadPoolTask(new ClearCenterSettingFilesTask(this)); GetEntityBase()->GetFunction()->PostThreadPoolTask(new ClearAd0Task(this)); #else RunTask* videoTask = new RunTask(this); videoTask->SetFlag(m_bReadyFlag ? 1 : 0); GetEntityBase()->GetFunction()->PostThreadPoolTask(videoTask); #endif e->SetHandled(); } break; case USER_EVT_FETCH: { FetchEvent* fetchEvt = dynamic_cast(e); fetchEvt->ctx->Answer(Error_InvalidState); e->SetHandled(); } break; case USER_EVT_GET_CARDSWIPER_STATUS_FINISHED: { m_bGetStatusRotate = FALSE; e->SetHandled(); } break; default: { Dbg("Unexpecetd Event(%d)", e->iEvt); } break; } return unRes; } void ResourceWatcherFSM::s0_on_exit() { } void ResourceWatcherFSM::s1_on_entry() { LOG_FUNCTION(); } unsigned int ResourceWatcherFSM::s1_on_event(FSMEvent* e) { LOG_FUNCTION(); unsigned int unRes = 0; switch (e->iEvt) { case USER_EVT_FETCH: { FetchEvent* fetchEvt = dynamic_cast(e); if (m_IsPadDevice) { fetchEvt->ctx->Ans.reserved1 = GetCardSwiperVal(); fetchEvt->ctx->Answer(Error_Succeed); } else { Dbg("In Not Pad MachineType, Receive Query CardSwiper Status Event"); fetchEvt->ctx->Answer(Error_NotSupport); } e->SetHandled(); } break; case USER_EVT_GET_CARDSWIPER_STATUS_FINISHED: { m_bGetStatusRotate = FALSE; e->SetHandled(); } break; case USER_EVT_CLEAR_UPLOADEDVIDEOFILES_FINISHED: { Dbg("%s::There are %d file(s), successfully delete %d file(s) in path %s", __FUNCTION__, e->param2, e->param1, (LPCTSTR)m_uploadedVideoDirPath); if (m_failDelCnt != 0) { CSimpleStringA strMsg = CSimpleStringA::Format("There are %d matched files should be deleted", m_failDelCnt); LogWarn(Severity_Middle, Error_Unexpect, 0, (LPCTSTR)strMsg); } ClearVideoFilesEnhanceTask* task = new ClearVideoFilesEnhanceTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } e->SetHandled(); break; case USER_EVT_CLEAR_VIDEOFILE_ENHANCE_FINISHED: e->SetHandled(); break; case USER_EVT_VERSION_CLEAR_FINISHED: e->SetHandled(); break; default: { Dbg("Unexpecetd Event(%d)", e->iEvt); } break; } return unRes; } void ResourceWatcherFSM::s1_on_exit() { } void ResourceWatcherFSM::s2_on_entry() { LOG_FUNCTION(); } unsigned int ResourceWatcherFSM::s2_on_event(FSMEvent* e) { LOG_FUNCTION(); unsigned int unRes = 0; switch (e->iEvt) { case USER_EVT_RUN: { e->SetHandled(); } break; case USER_EVT_FETCH: { FetchEvent* fetchEvt = dynamic_cast(e); if (m_IsPadDevice) { fetchEvt->ctx->Ans.reserved1 = GetCardSwiperVal(); fetchEvt->ctx->Answer(Error_Succeed); } else { Dbg("In Not Pad MachineType, Receive Query CardSwiper Status Event"); fetchEvt->ctx->Answer(Error_NotSupport); } e->SetHandled(); } break; case USER_EVT_GET_CARDSWIPER_STATUS_FINISHED: { m_bGetStatusRotate = FALSE; e->SetHandled(); } break; case USER_EVT_CLEAR_VIDEOFILE_ENHANCE_FINISHED: { } e->SetHandled(); break; } return unRes; } void ResourceWatcherFSM::s2_on_exit() { LOG_FUNCTION(); } void ResourceWatcherFSM::s3_on_entry() { LOG_FUNCTION(); m_bVideoClearReady = true; } unsigned int ResourceWatcherFSM::s3_on_event(FSMEvent* e) { LOG_FUNCTION(); unsigned int unRes = 0; switch (e->iEvt) { case USER_EVT_RUN: { e->SetHandled(); } break; case USER_EVT_FETCH: { FetchEvent* fetchEvt = dynamic_cast(e); if (m_IsPadDevice) { fetchEvt->ctx->Ans.reserved1 = GetCardSwiperVal(); fetchEvt->ctx->Answer(Error_Succeed); } else { Dbg("In Not Pad MachineType, Receive Query CardSwiper Status Event"); fetchEvt->ctx->Answer(Error_NotSupport); } e->SetHandled(); } break; case USER_EVT_GET_CARDSWIPER_STATUS_FINISHED: { m_bGetStatusRotate = FALSE; e->SetHandled(); } break; case USER_EVT_CLEAR_VIDEOFILE_ENHANCE: { ClearVideoFilesEnhanceTask* task = new ClearVideoFilesEnhanceTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } e->SetHandled(); break; case USER_EVT_CLEAR_VIDEOFILE_ENHANCE_FINISHED: { } e->SetHandled(); break; case USER_EVT_FILE_OPERAT: { OperateFileEvent* theEvt = dynamic_cast(e); OperateFileTask* theTask = new OperateFileTask(this, theEvt->m_ctx); GetEntityBase()->GetFunction()->PostThreadPoolTask(theTask); } e->SetHandled(); break; case USER_EVT_FILE_OPERAT_FINISHED: { } e->SetHandled(); break; case USER_EVT_GET_EVENTLOG: { GetEventLogEvent* theEvt = dynamic_cast(e); #if defined(_MSC_VER) GetEventLogTask* theTask = new GetEventLogTask(this, theEvt->m_ctx); GetEntityBase()->GetFunction()->PostThreadPoolTask(theTask); #else theEvt->m_ctx->Answer(Error_NotSupport); #endif //_MSC_VER } e->SetHandled(); break; case USER_EVT_GET_EVENTLOG_FINISHED: { } e->SetHandled(); break; } return unRes; } void ResourceWatcherFSM::s3_on_exit() { m_bVideoClearReady = false; } void ResourceWatcherFSM::readVideoStoreData() { LOG_FUNCTION(); CSmartPointer spCtSettingConfig; CSmartPointer spConfig; GetEntityBase()->GetFunction()->OpenConfig(Config_CenterSetting, spCtSettingConfig); GetEntityBase()->GetFunction()->OpenConfig(Config_Software, spConfig); // From CenterSetting --Josephus at 10:02:10 201759 spCtSettingConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "BackwardDays", m_nDayOfBackward); if (m_nDayOfBackward <= 0) { spConfig->ReadConfigValueInt("Video", "BackwardDays", m_nDayOfBackward); } else { Dbg("Detect BackwardDays from CentralSetting %d", m_nDayOfBackward); } if (m_nDayOfBackward <= 0 || m_nDayOfBackward > MAX_DAY_OF_BACKWARD) { Dbg("Detect BackwardDays(%d) is illegal and Set default %d", m_nDayOfBackward, DEFAULT_DAY_OF_BACKWARD); m_nDayOfBackward = DEFAULT_DAY_OF_BACKWARD; } int minSavedDay = 0; spCtSettingConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "MinSavedDays", minSavedDay); if (minSavedDay >= 1 && minSavedDay < DEFAULT_SAVE_DATE_COUNT) { m_nMinSavedDay = minSavedDay; Dbg("Detect MinSavedDays from CentralSetting %d", m_nMinSavedDay); } } ErrorCodeEnum ResourceWatcherFSM::OnInit() { LOG_FUNCTION(); #if defined(_MSC_VER) && defined(WIDE_CONDITION) setlocale(LC_ALL, "chs"); #endif ErrorCodeEnum erroCode = Error_Succeed; CSimpleStringA strtermState; GetEntityBase()->GetFunction()->GetSysVar("TerminalStage", strtermState); if (strtermState.IsStartWith("Z=")) { Dbg("in config mode"); m_bIsConfigMode = TRUE; } CSystemStaticInfo sysInfo; erroCode = GetEntityBase()->GetFunction()->GetSystemStaticInfo(sysInfo); if (erroCode != Error_Succeed) { Dbg("Get System Static info failed: %s.", SpStrError(erroCode)); return Error_Unexpect; } Dbg("%s, %s", sysInfo.strMachineType.GetData(), sysInfo.strTerminalID.GetData()); m_strTerminalNo = sysInfo.strTerminalID; if (!sysInfo.strMachineType.IsNullOrEmpty() && !sysInfo.strMachineType.Compare("RVC.Pad", true)) { m_IsPadDevice = TRUE; } m_bFirstRunAfterBoot = DetectIsFirstRunAtBoot(); Dbg("to initialize critical section..."); InitializeCriticalSection(&g_csVideoMoreClear); if (!m_bIsConfigMode) { erroCode = GetEntityBase()->GetFunction()->GetPath("LocalVideo", m_uploadedVideoDirPath); if (erroCode != Error_Succeed || m_uploadedVideoDirPath.IsNullOrEmpty()) { return Error_NotInit; } InitialVolumes(); InitBlackList(); readVideoStoreData(); m_bReadyFlag = IsNeedToFirstClear(); Dbg("Retrieve uploadedVideo path[%s], backwardDays(%d) done(%d)" , (LPCTSTR)m_uploadedVideoDirPath, m_nDayOfBackward, !m_bReadyFlag); void* pTmpData = NULL; ITimerListener* pListener = new TimerOutHelper(this, &ResourceWatcherFSM::HardwareInfoTimer, pTmpData); GetEntityBase()->GetFunction()->SetTimer(TIMER_HARDWARE_CHECK, pListener, MAX_HARDWARE_CHECK_TIME); Dbg("Set Hardware Timer!"); /*void* pTmpData2 = NULL; ITimerListener* pListener2 = new TimerOutHelper(this, &ResourceWatcherFSM::MainLinkDetectTimer, pTmpData2); GetEntityBase()->GetFunction()->SetTimer(TIMER_MAINLINK_CHECK, pListener2, MAX_MAINLINK_CHECK_TIME); Dbg("Set MainLinkDetect Timer!");*/ } return Error_Succeed; } ErrorCodeEnum ResourceWatcherFSM::OnExit() { LOG_FUNCTION(); GetEntityBase()->GetFunction()->KillTimer(TIMER_HARDWARE_CHECK); Dbg("Kill Timer!"); ClearVideoQueue(); DeleteCriticalSection(&g_csVideoMoreClear); return Error_Succeed; } void ResourceWatcherFSM::AfterInit() { LOG_FUNCTION(); CSmartPointer spCtSettingConfig; GetEntityBase()->GetFunction()->OpenConfig(Config_CenterSetting, spCtSettingConfig); //huchen add for set dns spCtSettingConfig->ReadConfigValue(GetEntityBase()->GetEntityName(), "DefaultDns", m_strDefaultDns); spCtSettingConfig->ReadConfigValue(GetEntityBase()->GetEntityName(), "BackupDns", m_strBackupDns); spCtSettingConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "EnableSetDns", m_nEnableSetDns); Dbg("Detect Dns from CentralSetting EnableSetDns: %d Default: %s, Backup: %s.", m_nEnableSetDns, m_strDefaultDns.GetData(), m_strBackupDns.GetData()); #if defined(_MSC_VER) if (!sysInfo.strMachineType.Compare("RVC.Desk2S", true)) { int nLastTaskTime(0); CSmartPointer spRunConfig; GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spRunConfig); spRunConfig->ReadConfigValueInt("Device", "SetAudioOutput", nLastTaskTime); CSmallDateTime lastSetTime(nLastTaskTime); Dbg("RunConfig SetAudioOutput time : %s", (LPCTSTR)lastSetTime.ToTimeString()); if (m_bFirstRunAfterBoot) { Dbg("last set audio output time is earlier than system boot time!"); Dbg("Start to Set Audio output device"); if (SetDefaultAudioDevice()) { spRunConfig->WriteConfigValue("Device", "SetAudioOutput", CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow())); } else { LogWarn(Severity_Middle, Error_AudioOut, 0, "Set default video output failed!!"); } } } #else if (m_bFirstRunAfterBoot) { UINT sysVer = 0; UploadSysVersionInfo(sysVer); ConfirmWindowEffectHasBeenOpen(); ConfirmDNSConfigHasSet(); Dbg("fetch os version: %u", sysVer); if (1031 < sysVer) { ConfirmDDEClipboardDisable(); ConfirmNotificationCenterDisable(); } else { RecoverDDEClipboardEnable(); } } #endif //_MSC_VER } int ResourceWatcherFSM::GetCardSwiperStatus() { LOG_FUNCTION(); ErrorCodeEnum errorCode = Error_Succeed; CardSwiperClient* client = NULL; CardSwiperService_QueryConnInfo_Req req; CardSwiperService_QueryConnInfo_Ans ans; QueryCardSwiper cardswiperStatus; BOOL bConnected = FALSE; // [Josephus in 7:05:25 2016/9/6] int lastStatus = m_cardswiperStatus; int errorTimes1 = 0, errorTimes2 = 0, errorTimes3 = 0; int sleepTime = 1500; const int errorMaxTimes = 2; m_bGetStatusRotate = TRUE; while (m_bGetStatusRotate) { if (client == NULL) { client = new CardSwiperClient(GetEntityBase()); } if (!bConnected) { errorCode = client->Connect(); if (errorCode != Error_Succeed) { if (errorTimes1 < errorMaxTimes) { errorTimes1++; Dbg("Connect to CardSwiper failed %s", SpStrError(errorCode)); Sleep(500); continue; } else { //errorTimes1++; Dbg("Connect to CardSwiper failed..."); // [Josephus in 16:15:37 2016/3/28] bConnected = FALSE; client->SafeDelete(); client = NULL; m_cardswiperStatus = 0; goto BroadCastPoint; } } else { Dbg("Connect to CardSwiper Success"); bConnected = TRUE; errorTimes3 = errorTimes2 = 0; } } errorCode = client->QueryConnInfo(req, ans, 3000); if (errorCode != Error_Succeed) { if (errorTimes2 < errorMaxTimes) { errorTimes2++; Dbg("Get CardSwiper status failed with code %s", SpStrError(errorCode)); Sleep(500); continue; } else { Dbg("Get CardSwiper status failed..."); bConnected = FALSE; client->GetFunction()->CloseSession(); client = NULL; m_cardswiperStatus = 0; } } else { errorTimes1 = errorTimes2 = errorTimes3 = 0; m_cardswiperStatus = ans.connect; } BroadCastPoint: if (lastStatus != m_cardswiperStatus) { Dbg("send broadcast for cardswiper status %d", m_cardswiperStatus); cardswiperStatus.status = m_cardswiperStatus; SpSendBroadcast(GetEntityBase()->GetFunction(), SP_MSG_OF(QueryCardSwiper), SP_MSG_SIG_OF(QueryCardSwiper), cardswiperStatus); lastStatus = m_cardswiperStatus; } break; } if (client) { if (bConnected) { client->GetFunction()->CloseSession(); } else { client->SafeDelete(); } client = NULL; } return 0; } void ResourceWatcherFSM::AppendVideoSizeTogether() { Dbg("Add UploadFile size together..."); #if defined(_MSC_VER) ULARGE_INTEGER uiAdditionBytes; CalculateWillUploadDirSize(uiAdditionBytes); mAllVideoFileSizeCal.QuadPart += uiAdditionBytes.QuadPart; diskInfo.SetUploadVideoDirSize(uiAdditionBytes); #else unsigned long long uiAdditionBytes; CalculateWillUploadDirSize(uiAdditionBytes); mAllVideoFileSizeCal += uiAdditionBytes; diskInfo.SetUploadVideoDirSize(uiAdditionBytes); #endif //_MSC_VER } void ResourceWatcherFSM::CalculateFreeDiskNeeded() { const_map_cu_iter citer = VideoDailyRecord.cbegin(); UINT uCount = 0; while (citer != VideoDailyRecord.cend()) { Dbg("date[%d]: %d", (citer->first), citer->second); uCount += citer->second; citer++; } Dbg("count %d and video file size#%d", uCount, m_VideoFiles.size()); diskInfo.CalAverRequreSpaceEachDay(mAllVideoFileSizeCal, uCount, VideoDailyRecord.size(), BASE_AVAILALBE_DATE_COUNT, mUiRequireBytes); } void ResourceWatcherFSM::RecordFreeDiskNeededToRunCfg() { CSmartPointer spConfigRun; GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); #if defined(RVC_OS_WIN) spConfigRun->WriteConfigValueHexInt("Video", "RequiredBytes", mUiRequireBytes.QuadPart); #else spConfigRun->WriteConfigValueHexInt("Video", "RequiredBytes", mUiRequireBytes); #endif //RVC_OS_WIN spConfigRun->WriteConfigValue("LastClearTime", "Video", (const char*)CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow())); m_bReadyFlag = false; } void ResourceWatcherFSM::GetFreeDiskNeededFromRunCfg() { CSmartPointer spConfigRun; GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); #if defined(_MSC_VER) spConfigRun->ReadConfigValueHexInt("Video", "RequiredBytes", mUiRequireBytes.QuadPart); Dbg("Retrieve from runcfg about required bytes: %llu", mUiRequireBytes.QuadPart); #else UINT64 value(0); spConfigRun->ReadConfigValueHexInt("Video", "RequiredBytes", value); mUiRequireBytes = value; Dbg("Retrieve from runcfg about required bytes: %llu", value); #endif //_MSC_VER } int ResourceWatcherFSM::CleanVideoFiles(int& newDeletedFilesNum, int initFlag) { LOG_FUNCTION(); newDeletedFilesNum = 0; ClearVideoQueue(); CSimpleStringA filePath = m_uploadedVideoDirPath; #if defined(_MSC_VER) filePath += "\\*"; #endif //_MSC_VER Dbg("(InitFlag:%d) filePath %s", initFlag, (LPCTSTR)filePath); newDeletedFilesNum = 0; m_failDelCnt = 0; const int nRet = RemoveExpireVideoFileAndRecord((LPCTSTR)filePath, newDeletedFilesNum, m_failDelCnt, initFlag); PrintVideEmurateResult(); Dbg("nRet: %d, new Deleted Files Num:%d, video counts:%d", nRet, newDeletedFilesNum, m_VideoFiles.size()); LOG_ASSERT(nRet - newDeletedFilesNum == m_VideoFiles.size()); if (!!initFlag) { AppendVideoSizeTogether(); CalculateFreeDiskNeeded(); RecordFreeDiskNeededToRunCfg(); } else { GetFreeDiskNeededFromRunCfg(); } return nRet; } #if defined(RVC_OS_WIN) void ResourceWatcherFSM::CalculateBackTime(PFILETIME ftResultTime, int days) { //Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). FILETIME ftCurTime, ftBackTime; GetSystemTimeAsFileTime(&ftCurTime); ULARGE_INTEGER uliCurTime, uliOffset, uliBackTime; uliCurTime.HighPart = ftCurTime.dwHighDateTime; uliCurTime.LowPart = ftCurTime.dwLowDateTime; if (days > 0) { uliOffset.QuadPart = UInt32x32To64(days * 24 * 60 * 60, 1e7); uliBackTime.QuadPart = uliCurTime.QuadPart - uliOffset.QuadPart; } else { uliOffset.QuadPart = UInt32x32To64(-1 * days * 24 * 60 * 60, 1e7); uliBackTime.QuadPart = uliCurTime.QuadPart + uliOffset.QuadPart; } ftBackTime.dwHighDateTime = uliBackTime.HighPart; ftBackTime.dwLowDateTime = uliBackTime.LowPart; *ftResultTime = ftBackTime; return; } BOOL ResourceWatcherFSM::CalculateWillUploadDirSize(ULARGE_INTEGER& uiBytesCal) { uiBytesCal.QuadPart = 0; #else void ResourceWatcherFSM::CalculateBackTime(time_t * ftResultTime, int days) { time_t ftCurTime = time(NULL);//获取当前时间 time_t ftBackTime = ftCurTime - (60 * 60 * 24 * days); *ftResultTime = ftBackTime; return; } BOOL ResourceWatcherFSM::CalculateWillUploadDirSize(unsigned long long& uiBytesCal) { uiBytesCal = 0; #endif //RVC_OS_WIN BOOL bRet = FALSE; CSimpleStringA uploadVideoPath; CSimpleStringA tmpValue; ErrorCodeEnum ec = GetEntityBase()->GetFunction()->GetPath(UPLOAD_VIDEO_PATH, uploadVideoPath); if (uploadVideoPath.GetLength() <= 0) ec = Error_Param; if (ec == Error_Succeed) { Dbg("UploadVideo path: %s", (LPCTSTR)uploadVideoPath); #if defined(_MSC_VER) CSimpleStringA filePath = uploadVideoPath + "\\*"; ULARGE_INTEGER uliSpaceSize; uliSpaceSize.QuadPart = 0; int nFileCnt = CalculateAllVideoSize(filePath, &uliSpaceSize); char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)uliSpaceSize.QuadPart); uiBytesCal.QuadPart = uliSpaceSize.QuadPart; #else uiBytesCal = 0; const int nFileCnt = CalculateAllVideoSize(uploadVideoPath, &uiBytesCal); char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)uiBytesCal); #endif //_MSC_VER Dbg("Result: Files(%d), Size: %s", nFileCnt, szResult); } return (ec == Error_Succeed); } int ResourceWatcherFSM::RemoveExpireVideoFileAndRecord(LPCTSTR dirName, int& deletedFileCnt, int& deleteFailedCnt, const int nFlag) { int fileCnt = 0; int fileLength = strlen(dirName); // =>=> /*foundFileData.cFileName[0] != '.'*/ !!! be careful for backdate call for the function. char searchFilePath[MAX_PATH] = { 0 }; char tempFilePath[MAX_PATH] = { 0 }; char displayTime[MAX_PATH] = { 0 }; #if defined(RVC_OS_WIN) WIN32_FIND_DATA foundFileData; HANDLE hFind; FILETIME ftRemoveTime; CalculateBackTime(&ftRemoveTime, m_nDayOfBackward); GetTimeFormatStr(displayTime, MAX_PATH, &ftRemoveTime); Dbg("The date backward to delete: %s", displayTime); hFind = FindFirstFile(dirName, &foundFileData); if (hFind == INVALID_HANDLE_VALUE) { Dbg("FindFirstFile failed (%u)", GetLastError()); return 0; } do { if ((foundFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { if (/*foundFileData.cFileName[0] != '.'*/FALSE) { strcpy_s(tempFilePath, dirName); tempFilePath[fileLength - 1] = '\0'; strcat_s(tempFilePath, foundFileData.cFileName); strcat_s(tempFilePath, "\\*"); fileCnt += RemoveExpireVideoFileAndRecord((LPCTSTR)tempFilePath, deletedFileCnt, deleteFailedCnt, nFlag); } } else { strcpy_s(searchFilePath, dirName); searchFilePath[fileLength - 1] = '\0'; strcat_s(searchFilePath, foundFileData.cFileName); if (nFlag == 1 && CompareVideoFileTime(&ftRemoveTime, &foundFileData.ftLastWriteTime) >= 0) { GetTimeFormatStr(displayTime, MAX_PATH, &foundFileData.ftLastWriteTime); if (DeleteFile(searchFilePath) != 0) { deletedFileCnt++; Dbg("Delete matched %s(%s) suc.", foundFileData.cFileName, displayTime); } else { deleteFailedCnt++; Dbg("Delete matched %s(%s) failed(%d).", foundFileData.cFileName, displayTime, GetLastError()); RecordVideoFileInfomation(searchFilePath, &foundFileData); } } else { RecordVideoFileInfomation(searchFilePath, &foundFileData); } fileCnt++; } } while (FindNextFile(hFind, &foundFileData)); FindClose(hFind); #else time_t tmp_time; CalculateBackTime(&tmp_time, m_nDayOfBackward); deletedFileCnt = deleteFailedCnt = 0; GetTimeFormatStr(displayTime, MAX_PATH, &tmp_time); Dbg("video backtrace time: %s", displayTime); struct stat st; if (stat(dirName, &st) < 0 || !S_ISDIR(st.st_mode)) { return 0; } DIR* d = opendir(dirName); if (!d) { return 0; } struct dirent* dp = NULL; while ((dp = readdir(d)) != NULL) { if ((!strcmp(dp->d_name, ".")) || (!strcmp(dp->d_name, ".."))) { continue; } strcpy(tempFilePath, dirName); if (strlen(tempFilePath) + strlen(dp->d_name) + 3 >= MAX_PATH) { Dbg("filePath is too long for current."); continue; } strcat(tempFilePath, "/"); strcat(tempFilePath, dp->d_name); if (-1 == stat(tempFilePath, &st)) { Dbg("stat video file: %s error: %d", tempFilePath, errno); continue; } const bool isdir = !!(S_ISDIR(st.st_mode)); if (isdir) { fileCnt += RemoveExpireVideoFileAndRecord((LPCTSTR)tempFilePath, deletedFileCnt, deleteFailedCnt, nFlag); } else { if (nFlag == 1 && st.st_mtime < tmp_time) { GetTimeFormatStr(displayTime, MAX_PATH, &st.st_mtime); if (RemoveFileA(tempFilePath)) { deletedFileCnt++; Dbg("Delete matched %s(%s) suc.", dp->d_name, displayTime); } else { deleteFailedCnt++; Dbg("Delete matched %s(%s) failed: %d", dp->d_name, displayTime, errno); } } RecordVideoFileInfomation(tempFilePath, &st); fileCnt++; } } closedir(d); #endif //RVC_OS_WIN return fileCnt; } #if defined(RVC_OS_WIN) BOOL ResourceWatcherFSM::GetCPUBrand(CSimpleStringA & csCpuBrand) { char CPUBrandString[0x40]; int CPUInfo[4] = { -1 }; unsigned nExIds; // Calling __cpuid with 0x80000000 as the InfoType argument // gets the number of valid extended IDs. __cpuid(CPUInfo, 0x80000000); nExIds = CPUInfo[0]; memset(CPUBrandString, 0, sizeof(CPUBrandString)); if (nExIds >= 0x80000004) { __cpuid(CPUInfo, 0x80000002); memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo)); __cpuid(CPUInfo, 0x80000003); memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo)); __cpuid(CPUInfo, 0x80000004); memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo)); // Display all the information in user-friendly format. csCpuBrand = CPUBrandString; Dbg("CPU Brand String: %s", (LPCTSTR)csCpuBrand); return TRUE; } Dbg("Current device is not supported for getting cpu brand 0x%08x.", nExIds); return FALSE; } void ResourceWatcherFSM::InitialCPUMarkInfor() { ErrorCodeEnum erroCode = Error_Succeed; CSmartPointer spConfig; erroCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Software, spConfig); if (erroCode != Error_Succeed) { Dbg("Open Config_Software failed %s.", SpStrError(erroCode)); return; } int nTmpValue1, nTmpValue2 = 0; erroCode = spConfig->ReadConfigValueInt("CPUMarkLevel", "High", nTmpValue1); if (erroCode == Error_Succeed/* && nTmpValue1 > 0*/) m_highPart = nTmpValue1; erroCode = spConfig->ReadConfigValueInt("CPUMarkLevel", "Low", nTmpValue2); if (erroCode == Error_Succeed/* && nTmpValue2 > 0*/) m_lowPart = nTmpValue2; Dbg("hight:%d > value >low:%d.", m_highPart, m_lowPart); return; } #endif //RVC_OS_WIN ErrorCodeEnum ResourceWatcherFSM::GetCpuType( SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum ec = Error_Succeed; #if defined(RVC_OS_WIN) ErrorCodeEnum erroCode = Error_Succeed; CSimpleStringA csCPUBrand; if (!GetCPUBrand(csCPUBrand)) { if (ctx != NULL) ctx->Answer(Error_Unexpect); return Error_Unexpect; } CSmartPointer spConfig; erroCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Software, spConfig); if (erroCode != Error_Succeed) { Dbg("Open Config_Software failed 0x%x.", erroCode); if (ctx != NULL) ctx->Answer(Error_DevLoadFileFailed); return Error_DevLoadFileFailed; } int nMark = 0; int level = 0; erroCode = spConfig->ReadConfigValueInt("CPUMark", (LPCTSTR)csCPUBrand, nMark); if (erroCode != Error_Succeed || nMark == 0) { Dbg("There are no level information about %s(mark:%d)(code:%d).", (LPCTSTR)csCPUBrand, nMark, erroCode); if (ctx != NULL) { ctx->Ans.brand = csCPUBrand; ctx->Ans.level = 0; ctx->Ans.reserved1 = nMark; ctx->Ans.reserved2 = ""; ctx->Answer(Error_Succeed); } } else { level = SelectMarkLevel(nMark); Dbg("Result: %s : %d(%d).", (LPCTSTR)csCPUBrand, nMark, level); if (ctx != NULL) { ctx->Ans.brand = csCPUBrand; ctx->Ans.level = level; ctx->Ans.reserved1 = nMark; ctx->Ans.reserved2 = ""; ctx->Answer(Error_Succeed); } } return Error_Succeed; #else ec = Error_NotSupport; LogWarn(Severity_Middle, ec, 0, CSimpleStringA::Format("%s is not supported!", __FUNCTION__)); if (ctx != NULL) { ctx->Answer(ec); } return ec; #endif //RVC_OS_WIN } BOOL ResourceWatcherFSM::RemoveDuplicateCenterSettingFiles() { LOG_FUNCTION(); ErrorCodeEnum erroCode = Error_Succeed; CSmartPointer spConfigRun; erroCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (erroCode != Error_Succeed) { Dbg("OpenConfig of 'Config_Run' failed 0x%x(%d).", erroCode, erroCode); return FALSE; } int nLastTaskTime(0); spConfigRun->ReadConfigValueInt("LastClearTime", "CenterSetting", nLastTaskTime); if (IsTodayDone(nLastTaskTime)) { return TRUE; } CSimpleStringA ssFilePath(true); erroCode = GetEntityBase()->GetFunction()->GetPath("cfg", ssFilePath); if (erroCode != Error_Succeed || ssFilePath.IsNullOrEmpty()) { Dbg("Get path of 'cfg' failed 0x%x(%d).", erroCode, erroCode); return FALSE; } #if defined(_MSC_VER) ssFilePath = ssFilePath + "\\*"; #endif //_MSC_VER Dbg("filePath %s", (LPCTSTR)ssFilePath); int nDelSuc = 0; int nDelFailed = 0; int nfileSum = ClearSpecifieFile(DFT_CenterSetting, ssFilePath, nDelSuc, nDelFailed); Dbg("#CenterSetting#There are %d file(s), delete: %d, failed: %d.", nfileSum, nDelSuc, nDelFailed); spConfigRun->WriteConfigValue("LastClearTime", "CenterSetting", (const char*)CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow())); return TRUE; } int ResourceWatcherFSM::ClearSpecifieFile(DealFileType fileType, LPCTSTR dirName, int& deletedFileCnt, int& deleteFailedCnt) { LOG_FUNCTION(); int nRes; int nfileCnt = 0; int fileLength = strlen(dirName); char searchFilePath[MAX_PATH] = { 0 }; char tempFilePath[MAX_PATH] = { 0 }; char displayTime[MAX_PATH] = { 0 }; #if defined(RVC_OS_WIN) WIN32_FIND_DATA fndFileData; HANDLE hFind; hFind = FindFirstFile(dirName, &fndFileData); if (hFind == INVALID_HANDLE_VALUE) { printf("FindFirstFile failed (%d) \n", GetLastError()); return -2; } do { if ((fndFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { if (fndFileData.cFileName[0] != '.') { memset(tempFilePath, 0, sizeof(tempFilePath)); strcpy_s(tempFilePath, dirName); tempFilePath[fileLength - 1] = '\0'; strcat_s(tempFilePath, fndFileData.cFileName); strcat_s(tempFilePath, "\\*"); int nRes = ClearSpecifieFile(fileType, (LPCTSTR)tempFilePath, deletedFileCnt, deleteFailedCnt); if (nRes >= 0) nfileCnt += nRes; } } else { memset((void*)searchFilePath, 0, MAX_PATH); strcpy_s(searchFilePath, dirName); searchFilePath[fileLength - 1] = '\0'; strcat_s(searchFilePath, fndFileData.cFileName); if (fileType == DFT_Ad0) { if (CompareFileTime(&mftAd0RemoveTime, &fndFileData.ftLastWriteTime) >= 0) { nRes = RemoveSpecifiedFile(fileType, searchFilePath, fndFileData.cFileName); } else { nRes = 0; } } else { nRes = RemoveSpecifiedFile(fileType, searchFilePath, fndFileData.cFileName); } if (nRes == -1) deleteFailedCnt++; else if (nRes == 1) deletedFileCnt++; nfileCnt++; } } while (FindNextFile(hFind, &fndFileData)); FindClose(hFind); #else struct stat st; if (stat(dirName, &st) < 0) { Dbg("stat for %s failed: %d %s", dirName, errno, strerror(errno)); return -2; } if (!S_ISDIR(st.st_mode)) { Dbg(" %s is not directory", dirName); return -2; } DIR* d = opendir(dirName); if (!d) { return -3; } struct dirent* dp = NULL; while ((dp = readdir(d)) != NULL) { if ((!strcmp(dp->d_name, ".")) || (!strcmp(dp->d_name, ".."))) { continue; } strcpy(tempFilePath, dirName); if (strlen(tempFilePath) + strlen(dp->d_name) + 3 >= MAX_PATH) { Dbg("filePath is too long for current."); continue; } strcat(tempFilePath, "/"); strcat(tempFilePath, dp->d_name); Dbg("fileName: %s", dp->d_name); struct stat stFile; stat(tempFilePath, &stFile); const bool isdir = !!(S_ISDIR(stFile.st_mode)); if (isdir && fileType != DFT_CenterSetting) { int nRes = ClearSpecifieFile(fileType, (LPCTSTR)tempFilePath, deletedFileCnt, deleteFailedCnt); if (nRes >= 0) nfileCnt += nRes; } else if (!isdir) { if (fileType != DFT_Ad0 || (CompareVideoFileTime(&mftAd0RemoveTime, &stFile.st_mtime) >= 0)) { nRes = RemoveSpecifiedFile(fileType, tempFilePath, dp->d_name); } else { nRes = 0; } if (nRes == -1) deleteFailedCnt++; else if (nRes == 1) deletedFileCnt++; nfileCnt++; } } closedir(d); #endif //RVC_OS_WIN return nfileCnt; } int ResourceWatcherFSM::RemoveSpecifiedFile(DealFileType fileType, LPCTSTR szFilePath, LPCTSTR szFileName) { CSimpleStringA ssFileName = szFileName; if (ssFileName.IsNullOrEmpty()) return FALSE; if ((fileType == DFT_CenterSetting && ssFileName.IsStartWith("centersetting", true) && !ssFileName.IsEndWith(".ini", true)) || fileType == DFT_Ad0 ) { if (RemoveFileA(szFilePath)) { Dbg("%s delete suc.", szFileName); return 1; } Dbg("%s delete failed %d.", szFileName, GetLastError()); return -1; } return 0; } #if defined(_MSC_VER) void ResourceWatcherFSM::RecordVideoFileInfomation(LPCTSTR lpFilePath, PWIN32_FIND_DATA pWfdata) { m_VideoFiles.push(new TmpFileInfo(lpFilePath, &(pWfdata->ftLastWriteTime), pWfdata->nFileSizeHigh, pWfdata->nFileSizeLow)); ULARGE_INTEGER uiTemp; uiTemp.HighPart = pWfdata->nFileSizeHigh; uiTemp.LowPart = pWfdata->nFileSizeLow; mAllVideoFileSizeCal.QuadPart += uiTemp.QuadPart; if (mMaxFileSize.QuadPart < uiTemp.QuadPart) { strcpy_s(szMaxSizeFilePath, lpFilePath); mMaxFileSize.QuadPart = uiTemp.QuadPart; } SyncUpdateVideoCreateDaily(&(pWfdata->ftLastWriteTime), 1); } void ResourceWatcherFSM::CleanMoreVideoFiles() { EnterCriticalSection(&g_csVideoMoreClear); ErrorCodeEnum erroCode = Error_Succeed; BOOL bOK = FALSE; CSmartPointer spConfigRun; ErrorCodeEnum ecRunCfg = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (m_VideoFiles.empty()) { int reseved = 0; m_bReadyFlag = IsNeedToFirstClear(); int nRes = CleanVideoFiles(reseved, m_bReadyFlag ? 1 : 0); if (nRes - reseved == 0) { Dbg("There are no any video files in facts."); SetSysValAndBroadcast(0, "There are no any video files in facts."); LeaveCriticalSection(&g_csVideoMoreClear); return; } } if (mUiRequireBytes.QuadPart == 0ui64) {//更新记录运行时,并等待下一次的自检执行。 Dbg("empty?"); int reseved = 0; CleanVideoFiles(reseved); Dbg("Wait next time to execute..."); LeaveCriticalSection(&g_csVideoMoreClear); return; } ULARGE_INTEGER uiSpaceRequired; ULARGE_INTEGER uiSpaceRealRequired; ULARGE_INTEGER uiFactor; int CurRank = 3; int BfRank = 0; if (spConfigRun->ReadConfigValueInt("Video", "RequiredRank", BfRank) != Error_Succeed || BfRank < 0) { BfRank = 0; } if (BfRank > 0) { ULARGE_INTEGER uiTotalBytes; ULARGE_INTEGER uiFreeDiskBytes; if (DiskInfo::GetDiskSpace((LPCTSTR)m_uploadedVideoDirPath, uiTotalBytes, uiFreeDiskBytes)) { //对比上次,剩余的可用磁盘空间更小了。 if (mUiCalibration.QuadPart >= uiFreeDiskBytes.QuadPart) { Dbg("Previous Set CurRank from %d to %d.", CurRank, BfRank); CurRank = BfRank; } mUiCalibration.QuadPart = uiFreeDiskBytes.QuadPart; } } char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; int nEnoughLevel = 0; do { uiFactor.QuadPart = 0; switch (CurRank) { case 3: uiSpaceRequired.QuadPart = mUiRequireBytes.QuadPart * DEFAULT_AVAILALBE_DATE_COUNT; break; case 2: uiSpaceRequired.QuadPart = mUiRequireBytes.QuadPart * LESS_AVAILALBE_DATE_COUNT; break; case 1: uiSpaceRequired.QuadPart = mUiRequireBytes.QuadPart * LEAST_AVAILALBE_DATE_COUNT; break; default: CurRank = 3; uiSpaceRequired.QuadPart = mUiRequireBytes.QuadPart * DEFAULT_AVAILALBE_DATE_COUNT; } ByteSprintf(szResult, (double)uiSpaceRequired.QuadPart); Dbg("Required size(%d): %s", CurRank, szResult); if (bOK = diskInfo.IsNeedToDoClearJobEx((LPCTSTR)m_uploadedVideoDirPath, uiSpaceRequired, uiFactor, &uiSpaceRealRequired)) { if (uiSpaceRealRequired.QuadPart == 0) { break; } char displayTime[MAX_PATH] = { 0 }; FILETIME ftSavedTime; //TODO: 暂时设置为至少保存两星期的录像文件,如果一天都不保留,那么 m_VideoFiles 要做即时更新 。2017-5-10 CalculateBackTime(&ftSavedTime, m_nMinSavedDay); GetTimeFormatStr(displayTime, MAX_PATH, &ftSavedTime); Dbg("SavedTime backtrace: %s", displayTime); ULARGE_INTEGER uiFreeBytes; uiFreeBytes.QuadPart = 0; UINT uDeletedCnt = 0, uFailedDeleteCnt = 0; BOOL bTrackBackStop = FALSE; while (!m_VideoFiles.empty() && uiFreeBytes.QuadPart < uiSpaceRealRequired.QuadPart) { TmpFileInfo* pCurFileInfo = m_VideoFiles.top(); if (pCurFileInfo != NULL) { SYSTEMTIME stUTC, stLocal; FileTimeToSystemTime(&(pCurFileInfo->mftEditTime), &stUTC); SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); if (CompareVideoFileTime(&ftSavedTime, &(pCurFileInfo->mftEditTime)) < 0) { Dbg("yet %s: %02d/%02d/%d %02d:%02d", pCurFileInfo->msFileName.c_str(), stLocal.wMonth, stLocal.wDay, stLocal.wYear, stLocal.wHour, stLocal.wMinute); bTrackBackStop = TRUE; break; } //if(TRUE) if (DeleteFile(pCurFileInfo->msFileName.c_str()) != 0) { ULARGE_INTEGER tmpBytes; tmpBytes.HighPart = pCurFileInfo->mDwFileSizeHeight; tmpBytes.LowPart = pCurFileInfo->mDwFileSizeLow; uiFreeBytes.QuadPart += tmpBytes.QuadPart; uDeletedCnt++; Dbg("Delete suc: %s: %02d/%02d/%d %02d:%02d", pCurFileInfo->msFileName.c_str(), stLocal.wMonth, stLocal.wDay, stLocal.wYear, stLocal.wHour, stLocal.wMinute); SyncUpdateVideoCreateDaily(&(pCurFileInfo->mftEditTime), -1); } else { Dbg("[DelFail] File(%s) %u", pCurFileInfo->msFileName.c_str(), GetLastError()); uFailedDeleteCnt++; } } m_VideoFiles.pop(); if (pCurFileInfo != NULL) delete pCurFileInfo; } char szOutput[DEFAULT_OUTPUT_FORMAT_SIZE] = { 0 }; char szOutput2[DEFAULT_OUTPUT_FORMAT_SIZE] = { 0 }; ByteSprintf(szOutput, (double)uiFreeBytes.QuadPart); ByteSprintf(szOutput2, (double)uiSpaceRealRequired.QuadPart); Dbg("Result(Rank#%d): Succeed deleted<%d>, Failed deleted<%d>, Deleted Size<%s> Real Required Size<%s>", CurRank, uDeletedCnt, uFailedDeleteCnt, szOutput, szOutput2); if (uiFreeBytes.QuadPart >= uiSpaceRealRequired.QuadPart) { break; } --CurRank; UINT uCount = 0; for (const_map_cu_iter citer = VideoDailyRecord.cbegin(); citer != VideoDailyRecord.cend(); citer++) { uCount += citer->second; } Dbg("FileCount(%d)(%d)", uCount, m_VideoFiles.size()); } else { LogError(Severity_Middle, Error_Unexpect, 0, "IsNeedToDoClearJobEx invoked failed !"); LeaveCriticalSection(&g_csVideoMoreClear); return; } } while (CurRank > 0); char szResult3[DEFAULT_OUTPUT_FORMAT_SIZE * 2] = { 0 }; if (CurRank < 3) { ULARGE_INTEGER uiTotalBytes; ULARGE_INTEGER uiFreeDiskBytes; if (DiskInfo::GetDiskSpace((LPCTSTR)m_uploadedVideoDirPath, uiTotalBytes, uiFreeDiskBytes)) { char szResult2[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)uiTotalBytes.QuadPart); ByteSprintf(szResult2, (double)uiFreeDiskBytes.QuadPart); double dFreeRate = (uiFreeDiskBytes.QuadPart * kConversion[3]) / (uiTotalBytes.QuadPart * kConversion[3]); sprintf_s(szResult3, "[Disk# %c:\\] total: %s, free: %s, rate: %.1lf%%.", m_uploadedVideoDirPath[0], szResult, szResult2, dFreeRate * 100); mUiCalibration.QuadPart = uiFreeDiskBytes.QuadPart; } else { strcpy_s(szResult3, "It's not enough disk space for recording video !"); } if (CurRank == 0) { CurRank = 4; } } else { strcpy_s(szResult3, "Disk space is enough for recording."); } if (BfRank != CurRank) { erroCode = spConfigRun->WriteConfigValueInt("Video", "RequiredRank", CurRank); } SetSysValAndBroadcast(CurRank, szResult3); LeaveCriticalSection(&g_csVideoMoreClear); return; } #else void ResourceWatcherFSM::RecordVideoFileInfomation(LPCTSTR lpFilePath, struct stat* pWfdata) { m_VideoFiles.push(new TmpFileInfo(lpFilePath, pWfdata->st_mtime, pWfdata->st_size)); mAllVideoFileSizeCal += pWfdata->st_size; if (mMaxFileSize < pWfdata->st_size) { strcpy(szMaxSizeFilePath, lpFilePath); mMaxFileSize = pWfdata->st_size; } SyncUpdateVideoCreateDaily(&pWfdata->st_mtime, 1); } void ResourceWatcherFSM::CleanMoreVideoFiles() { EnterCriticalSection(&g_csVideoMoreClear); ErrorCodeEnum erroCode = Error_Succeed; BOOL bOK = FALSE; char szResult3[DEFAULT_OUTPUT_FORMAT_SIZE * 2] = { 0 }; CSmartPointer spConfigRun; ErrorCodeEnum ecRunCfg = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (m_VideoFiles.empty() || mUiRequireBytes == 0) { int reseved = 0; int nRes = CleanVideoFiles(reseved, IsNeedToFirstClear() ? 1 : 0); if (nRes - reseved == 0) { Dbg("There are no any video files in facts."); //SetSysValAndBroadcast(0, "There are no any video files in facts."); LeaveCriticalSection(&g_csVideoMoreClear); return; } } int CurRank = 3; //default int BfRank = 0; if (spConfigRun->ReadConfigValueInt("Video", "RequiredRank", BfRank) != Error_Succeed || BfRank < 0) { BfRank = 0; } if (BfRank > 0) { unsigned long long uiTotalBytes; unsigned long long uiFreeDiskBytes; if (!DiskInfo::GetDiskSpace((LPCTSTR)m_uploadedVideoDirPath, uiTotalBytes, uiFreeDiskBytes)) { LeaveCriticalSection(&g_csVideoMoreClear); return; } //对比上次,剩余的可用磁盘空间更小了。 if (mUiCalibration >= uiFreeDiskBytes) { Dbg("Previous Set CurRank from %d to %d.", CurRank, BfRank); CurRank = BfRank == 4 ? 1 : BfRank; } mUiCalibration = uiFreeDiskBytes; } const int InitialRank = CurRank; char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; int nEnoughLevel = 0; unsigned long long uiFactor; char displayTime[MAX_PATH] = { 0 }; time_t ftSavedTime; CalculateBackTime(&ftSavedTime, m_nMinSavedDay); GetTimeFormatStr(displayTime, MAX_PATH, &ftSavedTime); Dbg("It's SavedTime backtrace: %s", displayTime); do { uiFactor = DEFAULT_AVAILALBE_DATE_COUNT; // 7天 if (CurRank == 2) uiFactor = LESS_AVAILALBE_DATE_COUNT; // 3天 else if (CurRank == 1) uiFactor = LEAST_AVAILALBE_DATE_COUNT; // 1天 const unsigned long long uiSpaceRequired = mUiRequireBytes * uiFactor; ByteSprintf(szResult, (double)uiSpaceRequired); Dbg("Required free disk size: %s, current rank: %d", szResult, CurRank); unsigned long long uiMoreSpaceRealRequired(0); unsigned long long uiAdjustment(0); if (diskInfo.IsNeedToDoClearJobEx((LPCTSTR)m_uploadedVideoDirPath, uiSpaceRequired, uiAdjustment, &uiMoreSpaceRealRequired) && uiMoreSpaceRealRequired) { unsigned long long uiNewFreeBytes(0); UINT uDeletedCnt = 0, uFailedDeleteCnt = 0; BOOL bTrackBackStop = FALSE; Dbg("the more space required: %llu.", uiMoreSpaceRealRequired); while (!m_VideoFiles.empty() && uiNewFreeBytes < uiMoreSpaceRealRequired) { TmpFileInfo* pCurFileInfo = m_VideoFiles.top(); if (pCurFileInfo != NULL) { GetTimeFormatStr(displayTime, MAX_PATH, &(pCurFileInfo->mftEditTime)); if (CompareVideoFileTime(&ftSavedTime, &(pCurFileInfo->mftEditTime)) < 0) { Dbg("stop at %s: %s", pCurFileInfo->msFileName.c_str(), displayTime); bTrackBackStop = TRUE; break; } if (RemoveFileA(pCurFileInfo->msFileName.c_str()) != 0) { uiNewFreeBytes += pCurFileInfo->ftSize; uDeletedCnt++; Dbg("Delete suc: %s: %s", pCurFileInfo->msFileName.c_str(), displayTime); SyncUpdateVideoCreateDaily(&(pCurFileInfo->mftEditTime), -1); } else { Dbg("[DelFail] File(%s) %d", pCurFileInfo->msFileName.c_str(), errno); uFailedDeleteCnt++; } } m_VideoFiles.pop(); if (pCurFileInfo != NULL) delete pCurFileInfo; } char szOutput[DEFAULT_OUTPUT_FORMAT_SIZE] = { 0 }; char szOutput2[DEFAULT_OUTPUT_FORMAT_SIZE] = { 0 }; ByteSprintf(szOutput, (double)uiNewFreeBytes); ByteSprintf(szOutput2, (double)uiMoreSpaceRealRequired); Dbg("Result(Rank#%d): Succeed deleted<%d>, Failed deleted<%d>, Deleted Size<%s> Real Required Size<%s>", CurRank, uDeletedCnt, uFailedDeleteCnt, szOutput, szOutput2); if (uiNewFreeBytes >= uiMoreSpaceRealRequired) { break; } else { --CurRank; } #ifdef WITH_DEBUG UINT uCount = 0; for (const_map_cu_iter citer = VideoDailyRecord.cbegin(); citer != VideoDailyRecord.cend(); citer++) { uCount += citer->second; } Dbg("FileCount(%d)(%d)", uCount, m_VideoFiles.size()); #endif } else if (InitialRank > CurRank) { break; } else { LeaveCriticalSection(&g_csVideoMoreClear); return; } } while (CurRank > 0); if (CurRank < 3) { unsigned long long uiTotalBytes; unsigned long long uiFreeDiskBytes; if (DiskInfo::GetDiskSpace((LPCTSTR)m_uploadedVideoDirPath, uiTotalBytes, uiFreeDiskBytes)) { char szResult2[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)uiTotalBytes); ByteSprintf(szResult2, (double)uiFreeDiskBytes); double dFreeRate = (uiFreeDiskBytes * kConversion[3]) / (uiTotalBytes * kConversion[3]); sprintf(szResult3, "[Disk# %s] total: %s, free: %s, rate: %.1lf%%.", m_uploadedVideoDirPath.GetData(), szResult, szResult2, dFreeRate * 100); mUiCalibration = uiFreeDiskBytes; } else { strcpy(szResult3, "It's not enough disk space for recording video !"); } } else { strcpy(szResult3, "Disk space is enough for recording."); } if (CurRank == 0) { CurRank = 4; } if (BfRank != CurRank) { erroCode = spConfigRun->WriteConfigValueInt("Video", "RequiredRank", CurRank); } SetSysValAndBroadcast(CurRank, szResult3); LeaveCriticalSection(&g_csVideoMoreClear); return; } #endif //_MSC_VER bool ResourceWatcherFSM::IsNeedToFirstClear() { int nLastTaskTime(0); CSmartPointer spRunConfig; GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spRunConfig); spRunConfig->ReadConfigValueInt("LastClearTime", "Video", nLastTaskTime); return !IsTodayDone(nLastTaskTime); } int ResourceWatcherFSM::ProcessFileDelete(LPCTSTR lpszPath, int& nDelSucCnt, int& nDelFailedCnt) { int fileCnt = 0; int fileLength = strlen(lpszPath); char* searchFilePath = new char[MAX_PATH]; char* tempFilePath = new char[MAX_PATH]; if (searchFilePath == NULL || tempFilePath == NULL) { if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return fileCnt; } ZeroMemory(searchFilePath, MAX_PATH); ZeroMemory(tempFilePath, MAX_PATH); #if defined(_MSC_VER) WIN32_FIND_DATA wfd; HANDLE hFind; hFind = FindFirstFile(lpszPath, &wfd); if (hFind == INVALID_HANDLE_VALUE) { Dbg("FindFirstFile failed GLE = %u.", GetLastError()); if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return 0; } do { if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { if (wfd.cFileName[0] != '.') { strcpy_s(tempFilePath, MAX_PATH, lpszPath); tempFilePath[fileLength - 1] = '\0'; if (strlen(tempFilePath) + strlen(wfd.cFileName) + 3 >= MAX_PATH) { Dbg("filePath is too long for current."); } else { strcat_s(tempFilePath, MAX_PATH, wfd.cFileName); CSimpleStringA tmpPath = tempFilePath; strcat_s(tempFilePath, MAX_PATH, "\\*"); int tDelSucCnt = 0, tDelFailedCnt = 0; fileCnt += ProcessFileDelete((LPCTSTR)tempFilePath, tDelSucCnt, tDelFailedCnt); if (tDelFailedCnt == 0 && !RemoveDirectoryA(tmpPath)) { Dbg("RemoveDirectoryA(%s) failed, GLE = %u.", (LPCTSTR)tmpPath, GetLastError()); nDelFailedCnt++; } nDelFailedCnt += tDelFailedCnt; nDelSucCnt += tDelSucCnt; } } } else { strcpy_s(searchFilePath, MAX_PATH, lpszPath); searchFilePath[fileLength - 1] = '\0'; strcat_s(searchFilePath, MAX_PATH, wfd.cFileName); if (DeleteFile(searchFilePath) != 0) { nDelSucCnt++; Dbg("Delete [%s] suc.", wfd.cFileName); } else { nDelFailedCnt++; Dbg("Delete [%s] failed, GLE = %u.", wfd.cFileName, GetLastError()); } fileCnt++; } } while (FindNextFileA(hFind, &wfd)); FindClose(hFind); #else struct stat st; if (stat(lpszPath, &st) < 0 || !S_ISDIR(st.st_mode)) { if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; Dbg("stat failed or is not dir."); return fileCnt; } DIR* d = opendir(lpszPath); if (!d) { if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; Dbg("opendir failed: %d", errno); return fileCnt; } struct dirent* dp = NULL; while ((dp = readdir(d)) != NULL) { if ((!strcmp(dp->d_name, ".")) || (!strcmp(dp->d_name, ".."))) { continue; } strcpy(tempFilePath, lpszPath); if (strlen(tempFilePath) + strlen(dp->d_name) + 3 >= MAX_PATH) { Dbg("filePath is too long for current."); continue; } strcat(tempFilePath, "/"); strcat(tempFilePath, dp->d_name); stat(tempFilePath, &st); bool isdir = !!(S_ISDIR(st.st_mode)); if (isdir) { int tDelSucCnt = 0, tDelFailedCnt = 0; fileCnt += ProcessFileDelete((LPCTSTR)tempFilePath, tDelSucCnt, tDelFailedCnt); if (tDelFailedCnt == 0 && rmdir(tempFilePath) != 0) { Dbg("rmdir(%s) failed, GLE = %u.", (LPCTSTR)tempFilePath, errno); nDelFailedCnt++; } nDelFailedCnt += tDelFailedCnt; nDelSucCnt += tDelSucCnt; } else { if (RemoveFileA(tempFilePath)) { nDelSucCnt++; Dbg("Delete [%s] suc.", dp->d_name); } else { nDelFailedCnt++; Dbg("RemoveFileA [%s] failed, GLE = %u.", tempFilePath, errno); } fileCnt++; } } closedir(d); #endif //_MSC_VER if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; searchFilePath = NULL; tempFilePath = NULL; return fileCnt; } BOOL ResourceWatcherFSM::DeleteVersionPackage() { LOG_FUNCTION(); BOOL bRet = FALSE; ErrorCodeEnum erroCode = Error_Succeed; CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer spConfigRun; CSystemStaticInfo info; if (pFunc->GetSystemStaticInfo(info) != Error_Succeed) { LogError(Severity_Middle, erroCode, 0, "Get system static info error"); return FALSE; } Dbg("Current version: %s", (LPCTSTR)info.InstallVersion.ToString()); int nLastTaskTime = 0; int nLstFlag = 0; UINT64 utVersion = 0; pFunc->OpenConfig(Config_Run, spConfigRun); spConfigRun->ReadConfigValueHexInt("VersionClear", "OptVer", utVersion); spConfigRun->ReadConfigValueInt("VersionClear", "LastCondi", nLstFlag); //last times is failed or not? failed:true spConfigRun->ReadConfigValueInt("VersionClear", "LastTime", nLastTaskTime); CVersion optVer(utVersion); SYSTEMTIME stTaskTime = CSmallDateTime(nLastTaskTime).ToSystemTime(); Dbg("LastTime<%04d-%02d-%02d %02d:%02d:%02d>: OptVer: %s, LastCondi: %d", stTaskTime.wYear, stTaskTime.wMonth, stTaskTime.wDay, stTaskTime.wHour, stTaskTime.wMinute, stTaskTime.wSecond, (LPCTSTR)optVer.ToString(), nLstFlag); //判断是否需要被清理 if (optVer.IsValid() && optVer == info.InstallVersion && !nLstFlag) { Dbg("VersionPackage cleaning has been done before."); return TRUE; } CSimpleStringA strRunInfo, strStartTime; if (m_pEntity->GetFunction()->GetPath("RunInfo", strRunInfo) == Error_Succeed) { strStartTime = strRunInfo + "/runcfg/starttime.dat"; if (!ExistsFileA(strStartTime.GetData())) { Dbg("upgrade porcess done, try to delete version files.");//完成升级过程,通过 } else { Dbg("upgrade process is not end ,should not delete version files."); return FALSE;//升级未完成,不进行删除 } } else { Dbg("upgrade process is not end ,get runinfo path is error, should not delete version files."); return FALSE;//失败,继续等待 } //获取当前目录下的文件夹名称, 将符合命名规则的终端版本名称push_back CSimpleStringA csPath; ErrorCodeEnum Error = m_pEntity->GetFunction()->GetPath("RootVer", csPath); //获取当前版本路劲 例如:C:\Run if (Error_Succeed == Error) { if (csPath.IsNullOrEmpty()) { Dbg("get currVer path is null"); return FALSE; } else { /*csPath.Append("/version");*/ Dbg("CUR VERSION PATH = %s.", csPath.GetData()); } } else { Dbg("get upgradeVer path is error"); return FALSE; } //vector intallInfoVects; vector intallInfoVects; vector files; DIR* dp; struct dirent* dirp; if ((dp = opendir(csPath.GetData())) != NULL) { while ((dirp = readdir(dp)) != NULL) { //files.push_back(string(dirp->d_name)); CInstallInfo verInfo = {}; DWORD dwMajor(0), dwMinor(0), dwRevision(0), dwBuild(0); int n = sscanf(dirp->d_name, "%d.%d.%d.%d", &dwMajor, &dwMinor, &dwRevision, &dwBuild); if (n != 4) { Dbg("Not version file.[%s]", dirp->d_name); continue; } else { CVersion verName(dwMajor, dwMinor, dwRevision, dwBuild); if (verName.IsValid() && verName < info.InstallVersion) //对高于自身版本的文件不予删除 { //verInfo.InstallVersion = verName; intallInfoVects.push_back(verName); } else { Dbg("Not version file.[%s]", dirp->d_name); } } } closedir(dp); } CSimpleStringA upPath; ErrorCodeEnum upError = m_pEntity->GetFunction()->GetPath("Upgraded", upPath); if (Error_Succeed != upError) { Dbg("get Upgraded path error"); return FALSE; } DIR* updp; struct dirent* updirp; if ((updp = opendir(upPath.GetData())) != NULL) { while ((updirp = readdir(updp)) != NULL) { char szPath[MAX_VERSION_PATH] = { 0 }; strcat(szPath, upPath.GetData()); CSimpleStringA tmpDirPath = szPath; strcat(szPath, "/"); strcat(szPath, updirp->d_name); Dbg("operating Upgrade path: [%s][%s]", (LPCTSTR)tmpDirPath, szPath); RemoveFileA(szPath); } closedir(updp); } /*CVersion lastVer = info.PreviousInstallVersion; while (lastVer.IsValid()) { CInstallInfo lastVerInfo = {}; erroCode = pFunc->GetInstallInfo(lastVer, lastVerInfo); if (erroCode != Error_Succeed) { break; } intallInfoVects.push_back(CInstallInfoEx(lastVerInfo)); lastVer = lastVerInfo.PreviousInstallVersion; }*/ int verSaved = DEFAULT_VERSION_SAVED_COUNT; int tmpSaved = 0; CSmartPointer spFunction = this->GetEntityBase()->GetFunction(); CSmartPointer spConfig; spFunction->OpenConfig(Config_Software, spConfig); spConfig->ReadConfigValueInt("VersionSaved", "default", tmpSaved); if (tmpSaved > DEFAULT_VERSION_SAVED_COUNT) { verSaved = tmpSaved; } int nPackCount = intallInfoVects.size(); Dbg("Install Package's count: %d", nPackCount); bool bFailFlag = false; int nDelVersionCnt = 0; if (nPackCount != 0) { int nSavedCount = 0; sort(intallInfoVects.begin(), intallInfoVects.end()); //vector::iterator iter = intallInfoVects.begin(); vector::reverse_iterator riter = intallInfoVects.rbegin(); while (riter != intallInfoVects.rend()) { //Dbg("InstallPackage Info: %s, SwithOverDate: %s", (LPCTSTR)iter->InstallVersion.ToString(), (LPCTSTR)iter->tmSwithOverDate.ToTimeString()); Dbg("InstallPackage Info: %s", (LPCTSTR)(*riter).ToString()); if (++nSavedCount <= verSaved) { Dbg("Save above version"); riter++; continue; } //if (!DeleteSpecificeVersionDir(iter->InstallVersion)) if(!DeleteSpecificeVersionDir(*riter)) bFailFlag = true; else nDelVersionCnt++; riter++; } } nLstFlag = bFailFlag ? 1 : 0; spConfigRun->WriteConfigValueHexInt("VersionClear", "OptVer", info.InstallVersion.GetVersion64()); spConfigRun->WriteConfigValueInt("VersionClear", "LastCondi", nLstFlag); spConfigRun->WriteConfigValue("VersionClear", "LastTime", (LPCTSTR)CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow())); string warn = "Delete Version files count : " + to_string(nDelVersionCnt); LogWarn(Severity_Low, Error_Debug, LOG_WARN_VER_DELETE, CSimpleStringA::Format("%s", warn.c_str())); return TRUE; } BOOL ResourceWatcherFSM::DeleteSpecificeVersionDir(CVersion version) { ErrorCodeEnum erroCode = Error_Unexpect; CSimpleStringA strPath; if (GetEntityBase()->GetFunction()->GetPath("RootVer", strPath) != Error_Succeed) return FALSE; strPath = strPath + SPLIT_SLASH_STR + version.ToString(); if (!ExistsDirA(strPath)) { Dbg("Directory(%s) Not Existed, Maybe delete before !!", strPath.GetData()); return TRUE; } CSimpleStringA tmpDirPath = strPath; #if defined(_MSC_VER) tmpDirPath += "\\*"; #endif //_MSC_VER Dbg("operating version path: [%s][%s]", (LPCTSTR)tmpDirPath, (LPCTSTR)strPath); int nDelSuc = 0, nDelFail = 0, nFileCount = 0; nFileCount = ProcessFileDelete((LPCTSTR)tmpDirPath, nDelSuc, nDelFail); Dbg("Process result(%s): count(%d), suc(%d), failed(%d).", tmpDirPath.GetData(), nFileCount, nDelSuc, nDelFail); #if defined(_MSC_VER) if (nDelFail != 0 || !RemoveDirectoryA(tmpDirPath)) { Dbg("Unexpect condition happen: (%d)(%u).", nDelFail, GetLastError()); #else if (nDelFail != 0 || rmdir(tmpDirPath) != 0) { Dbg("Unexpect condition happen: (%d)", nDelFail); #endif //_MSC_VER return FALSE; } return TRUE; } #if defined(_MSC_VER) int ResourceWatcherFSM::CalculateAllVideoSize(LPCTSTR lpszPath, PULARGE_INTEGER puliSpaceBytes) { int fileCnt = 0; int fileLength = strlen(lpszPath); char* searchFilePath = new char[MAX_PATH]; char* tempFilePath = new char[MAX_PATH]; if (searchFilePath == NULL || tempFilePath == NULL) { if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return fileCnt; } ZeroMemory(searchFilePath, MAX_PATH); ZeroMemory(tempFilePath, MAX_PATH); WIN32_FIND_DATA wfd; HANDLE hFind; hFind = FindFirstFile(lpszPath, &wfd); if (hFind == INVALID_HANDLE_VALUE) { Dbg("FindFirstFile failed GLE = %u.", GetLastError()); if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return 0; } do { if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { if (wfd.cFileName[0] != '.') { strcpy_s(tempFilePath, MAX_PATH, lpszPath); tempFilePath[fileLength - 1] = '\0'; if (strlen(tempFilePath) + strlen(wfd.cFileName) + 3 >= MAX_PATH) { Dbg("filePath is too long for current."); } else { strcat_s(tempFilePath, MAX_PATH, wfd.cFileName); strcat_s(tempFilePath, MAX_PATH, "\\*"); fileCnt += CalculateAllVideoSize((LPCTSTR)tempFilePath, puliSpaceBytes); } } } else { strcpy_s(searchFilePath, MAX_PATH, lpszPath); searchFilePath[fileLength - 1] = '\0'; strcat_s(searchFilePath, MAX_PATH, wfd.cFileName); ULARGE_INTEGER uiTemp; uiTemp.HighPart = wfd.nFileSizeHigh; uiTemp.LowPart = wfd.nFileSizeLow; puliSpaceBytes->QuadPart += uiTemp.QuadPart; SyncUpdateVideoCreateDaily(&wfd.ftLastWriteTime, 1); fileCnt++; } } while (FindNextFileA(hFind, &wfd)); FindClose(hFind); if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return fileCnt; } #else int ResourceWatcherFSM::CalculateAllVideoSize(LPCTSTR lpszPath, unsigned long long* puliSpaceBytes) { int fileCnt = 0; int fileLength = strlen(lpszPath); char* searchFilePath = new char[MAX_PATH]; char* tempFilePath = new char[MAX_PATH]; if (searchFilePath == NULL || tempFilePath == NULL) { if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return fileCnt; } ZeroMemory(searchFilePath, MAX_PATH); ZeroMemory(tempFilePath, MAX_PATH); struct stat st; if (stat(lpszPath, &st) < 0 || !S_ISDIR(st.st_mode)) { if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return fileCnt; } DIR* d = opendir(lpszPath); if (!d) { if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return fileCnt; } struct dirent* dp = NULL; while ((dp = readdir(d)) != NULL) { if ((!strcmp(dp->d_name, ".")) || (!strcmp(dp->d_name, ".."))) { continue; } strcpy(tempFilePath, lpszPath); if (strlen(tempFilePath) + strlen(dp->d_name) + 3 >= MAX_PATH) { Dbg("filePath is too long for current."); continue; } strcat(tempFilePath, "/"); strcat(tempFilePath, dp->d_name); stat(tempFilePath, &st); const bool isdir = !!(S_ISDIR(st.st_mode)); if (isdir) { fileCnt += CalculateAllVideoSize((LPCTSTR)tempFilePath, puliSpaceBytes); } else { *puliSpaceBytes += st.st_size; SyncUpdateVideoCreateDaily(&st.st_mtime, 1); fileCnt++; } } closedir(d); if (searchFilePath) delete[] searchFilePath; if (tempFilePath) delete[] tempFilePath; return fileCnt; } #endif //_MSC_VER void ResourceWatcherFSM::SelfTest(EntityTestEnum eTestType, CSmartPointer pTransactionContext) { static uint32_t times = 0; pTransactionContext->SendAnswer(Error_Succeed); times++; if (m_bVideoClearReady && times > 60 * 2) { //2 hour per times times = 0; PostEventFIFO(new FSMEvent(USER_EVT_CLEAR_VIDEOFILE_ENHANCE)); } } void ResourceWatcherFSM::SetSysValAndBroadcast(DWORD dwVal, LPCTSTR lpszMessage) { static DWORD dwOldVal = (DWORD)-1; CSmartPointer spFunction = this->GetEntityBase()->GetFunction(); CSimpleStringA csVPStatus = VIDEO_SPACE_UNKNOWN; CSimpleStringA csNewVPSatus = VIDEO_SPACE_UNKNOWN; spFunction->GetSysVar(SYSVAR_DISKSTATEUS_FOR_VIDEO, csVPStatus); if (dwVal == 4) { csNewVPSatus = VIDEO_SPACE_INSUFF_FATAL; LogError(Severity_High, Error_TooSmallBuffer, LOG_ERR_RES_VIDEO_INSUFFICIENT, lpszMessage); } else if (dwVal == 2) { csNewVPSatus = VIDEO_SPACE_INSUFF_LITTLE; if (dwVal != dwOldVal) LogWarn(Severity_Middle, Error_TooSmallBuffer, LOG_WARN_RES_VIDEO_INSUFFICIENT, lpszMessage); } else if (dwVal == 1) { csNewVPSatus = VIDEO_SPACE_INSUFF_LESS; if (dwVal != dwOldVal) LogWarn(Severity_Low, Error_TooSmallBuffer, LOG_WARN_RES_VIDEO_INSUFFICIENT, lpszMessage); } else if (dwVal == 3) { csNewVPSatus = VIDEO_SPACE_SUFFICIENT; if (dwVal != dwOldVal) LogEvent(Severity_High, LOG_EVT_RES_VIDEO_SUFFICIENT, lpszMessage); } else if (dwVal == 0) { if (dwVal != dwOldVal) LogEvent(Severity_High, LOG_EVT_RES_VIDEO_SUFFICIENT, lpszMessage); } else { Dbg("Unknow dwVal: %d", dwVal); } if (csNewVPSatus != csVPStatus) { ErrorCodeEnum eRet = spFunction->SetSysVar(SYSVAR_DISKSTATEUS_FOR_VIDEO, csNewVPSatus); Dbg("SetSysVar(%s) from '%s' to '%s' returned %d", SYSVAR_DISKSTATEUS_FOR_VIDEO , (LPCTSTR)csVPStatus , (LPCTSTR)csNewVPSatus , eRet); } dwOldVal = dwVal; } BOOL ResourceWatcherFSM::InitialDirectoryEntity(LPCTSTR lpszPath, DWORD & dwFileCnt, const DWORD dwFilterAttributes) { LOG_FUNCTION(); if (lpszPath == NULL) { SetLastError(ERROR_INVALID_PARAMETER); LogWarn(Severity_Middle, Error_Param, ERROR_INVALID_PARAMETER, "Null file path !"); return FALSE; } #if defined(_MSC_VER) HANDLE hFile = CreateFileA( lpszPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile == INVALID_HANDLE_VALUE) { Dbg("CreateFileA(%s) failed", lpszPath); return FALSE; } #endif //_MSC_VER m_FileEntry.SubFiles.Clear(); m_FileEntry.FileNamesBuffer.Clear(); m_FileEntry.Current.Clear(); DWORD dwLocate; Append(m_FileEntry.FileNamesBuffer, (PBYTE)lpszPath, strlen(lpszPath), dwLocate); m_FileEntry.Current.mNameOffset = dwLocate; m_FileEntry.Current.mNameLength = strlen(lpszPath); #if defined(_MSC_VER) GetFileTime(hFile, (LPFILETIME)&m_FileEntry.Current.mftCreate, (LPFILETIME)&m_FileEntry.Current.mftAccess, (LPFILETIME)&m_FileEntry.Current.mftModified); CloseHandle(hFile); hFile = NULL; m_FileEntry.Current.mAttributes = GetFileAttributesA(lpszPath); m_FileEntry.Current.mFileSize = 0; #else struct stat st; if (stat(lpszPath, &st) < 0) { Dbg("stat %s failed.", lpszPath); return FALSE; } //GetFileTime m_FileEntry.Current.mftCreate = st.st_ctime; m_FileEntry.Current.mftAccess = st.st_atime; m_FileEntry.Current.mftModified = st.st_mtime; m_FileEntry.Current.mAttributes = 0; //GetFileAttributesA if (S_ISDIR(st.st_mode)) { m_FileEntry.Current.mFileSize = 0; m_FileEntry.Current.mAttributes |= FILE_ATTRIBUTE_DIRECTORY; } else { m_FileEntry.Current.mFileSize = st.st_size; } if (m_FileEntry.Current.mAttributes == 0) m_FileEntry.Current.mAttributes = FILE_ATTRIBUTE_ARCHIVE; if (!(st.st_mode & S_IWUSR)) m_FileEntry.Current.mAttributes |= FILE_ATTRIBUTE_READONLY; #endif //_MSC_VER DWORD dwDir = 0, dwFile = 0; GetSubFileInfors(&m_FileEntry, dwDir, dwFile, dwFilterAttributes); Dbg("Flag: dwDir:%u, dwFile: %u", dwDir, dwFile); DisplayFileEntities(&m_FileEntry); dwFileCnt = dwDir + dwFile; #if defined(RVC_OS_LINUX) m_FileEntry.Current.mFileSize = dwFileCnt; #endif //RVC_OS_LINUX return TRUE; } DWORD ResourceWatcherFSM::InitialVolumes() { LOG_FUNCTION(); UINT uCount = 0; #if defined(RVC_OS_WIN) /*获取磁盘信息,该坐标下的内容作为是否遍历的标识*/ if (!sBDiskValStatus[MAX_VOLUME_COUNT]) { CHAR szDrivers[BUFSIZE] = { 0 }; CHAR szVolumeName[MAX_PATH] = { 0 }; CHAR szFileSysName[MAX_PATH] = { 0 }; BOOL bRet = GetLogicalDriveStringsA(BUFSIZE - 1, szDrivers); if (bRet) { Dbg("szDrivers: %s", szDrivers); for (CHAR* pTemp = szDrivers; *pTemp != '\0'; pTemp += 4) { if (*pTemp >= 'a' && *pTemp <= 'z') *pTemp -= 32; const int nDriNum = *pTemp - 'A'; if (DRIVE_FIXED == GetDriveType(pTemp)) { DWORD dwMaxCompLen, dwFileSystemFlags; bRet = GetVolumeInformation(pTemp, szVolumeName, MAX_PATH, NULL, &dwMaxCompLen, &dwFileSystemFlags, szFileSysName, MAX_PATH); sBDiskValStatus[nDriNum] = TRUE; uCount++; } else { sBDiskValStatus[nDriNum] = FALSE; } } } if (uCount > 0) { sBDiskValStatus[MAX_VOLUME_COUNT] = TRUE; } } m_FileEntry.SubFiles.Clear(); m_FileEntry.FileNamesBuffer.Clear(); m_FileEntry.Current.Clear(); uCount = 0; ULARGE_INTEGER uiTotalBytes, uiTotalFreeBytes; if (sBDiskValStatus[MAX_VOLUME_COUNT]) { m_FileEntry.Current.mLevel = -2; //mark parent of volume -2-level char szVolume[8] = { 0 }; for (int i = 0; i < MAX_VOLUME_COUNT; ++i) { if (sBDiskValStatus[i]) { szVolume[0] = i + 'A'; szVolume[1] = ':'; szVolume[2] = '\0'; CSimpleFileComponent volume; if (DiskInfo::GetDiskSpace(szVolume, uiTotalBytes, uiTotalFreeBytes)) { volume.mFileSize = uiTotalFreeBytes.QuadPart; } volume.mLevel = 0; volume.mNameLength = strlen(szVolume); Append(m_FileEntry.FileNamesBuffer, (PBYTE)szVolume, volume.mNameLength, volume.mNameOffset); volume.mAttributes = 0; m_FileEntry.SubFiles.Append(&volume, 0, 1); uCount++; } } } DisplayFileEntities(&m_FileEntry); #else #endif //RVC_OS_WIN return uCount; } DWORD ResourceWatcherFSM::ProcessFileOperation( const SpReqAnsContext::Pointer & ctx) { if (ctx == NULL) { return 0; } ResourceWatcherService_OperateFile_Req& req = ctx->Req; ResourceWatcherService_OperateFile_Ans& ans = ctx->Ans; { ans.header = ""; ans.attachment1 = 0; ans.attachment2 = ""; ans.fileSize = 0ULL; ans.ftCreate = 0ULL; ans.ftModified = 0ULL; ans.ftAccess = 0ULL; ans.fileAttribute = 0U; ans.count = 0; } CSimpleStringA strCurrent(true); size_t nCurLen = req.current.GetLength(); Dbg("size of current dir: %d", nCurLen); if (!req.current.IsNullOrEmpty()) { CSimpleStringA strTemp = req.current.Trim(); size_t len = req.current.GetLength(); while (len > 0 && (strTemp[len - 1] == '\\' || strTemp[len - 1] == '/')) { strTemp[len - 1] = '\0'; len--; } if (len > 0) { strCurrent = strTemp.Trim(); nCurLen = strCurrent.GetLength(); LOG_ASSERT(len == nCurLen); Dbg("size of strCurrent: %d", nCurLen); } } BOOL bCurNull = strCurrent.IsNullOrEmpty(); if (!bCurNull) { int nRes = FilterFilePathAhead(strCurrent, req.mode); if (nRes != 0) { ans.result = OPT_FILE_RES_FAILED; CSimpleStringA strTxt; switch (nRes) { case -1: case -2: strTxt = "文件路径参数错误。"; break; case -3: strTxt = "终端指定磁盘不存在。"; break; case 1: strTxt = "操作非法:不允许删除盘符。"; break; case 2: strTxt = "请求的操作无权限。"; break; default: strTxt = "操作失败,原因未知。"; break; } ans.attachment1 = strTxt.GetLength(); ans.attachment2 = strTxt; ctx->Answer(Error_Succeed); Dbg("Try to (option:%d) [%s] failed (%d): %s", req.mode, (LPCTSTR)strCurrent, nRes, (LPCTSTR)strTxt); return nRes; } } FileType type = FT_Unknown; IsPathExisted(strCurrent, type); int count = 0; ans.count = 0; ans.result = OPT_FILE_RES_INVALID; bool bNeedToRefleshHeader = false; bool bNeedToSetCtxEntities = false; bool bNeedToRefleshEntity = false; int updateLevel = 0; switch (ctx->Req.mode) { case OPT_FILE_CMD_SPREAD: //0 { DWORD dwRes = 0; if (!bCurNull && (type == FT_Unknown || type == FT_File)) { ans.result = OPT_FILE_RES_FAILED; ans.attachment1 = GetErrorMessage(ans.attachment2, "请求的文件不存在或类型不正确。"); Dbg("Before Initial File Entity failed: %s", ans.attachment2.GetData()); break; } DWORD dwFilterAttributes = (DWORD)(ctx->Req.filter1); if (bCurNull) { #if defined(_MSC_VER) dwRes = InitialVolumes(); #else if (!InitialDirectoryEntity("/", dwRes, dwFilterAttributes)) { ans.result = OPT_FILE_RES_FAILED; ans.attachment1 = GetErrorMessage(ans.attachment2, "获取根目录列表失败"); Dbg("Initial File Entity failed: %s", ans.attachment2.GetData()); break; } #endif //_MSC_VER } else if (!InitialDirectoryEntity(strCurrent, dwRes, dwFilterAttributes)) { ans.result = OPT_FILE_RES_FAILED; ans.attachment1 = GetErrorMessage(ans.attachment2, "获取文件列表失败"); Dbg("Initial File Entity failed: %s", ans.attachment2.GetData()); break; } Dbg("%d VS %d", dwRes, m_FileEntry.SubFiles.GetCount()); LOG_ASSERT(dwRes == m_FileEntry.SubFiles.GetCount()); count = dwRes; ans.result = OPT_FILE_RES_SUCCESS; bNeedToSetCtxEntities = true; bNeedToRefleshHeader = true; } break; case OPT_FILE_CMD_EXECUTE://1 { if (type != FT_File) { Dbg("Invalid file type !"); ans.result = OPT_FILE_RES_INVALID; ans.attachment2 = "非可打开或执行的文件类型(目录或其他)"; ans.attachment1 = ans.attachment2.GetLength(); break; } LPCTSTR lpParam = NULL; if (req.attachment1 > 0 && req.attachment2.GetLength() > 0) lpParam = req.attachment2; const DWORD dwRes = ExecuteFile(strCurrent, lpParam); ans.result = dwRes ? OPT_FILE_RES_FAILED : OPT_FILE_RES_SUCCESS; if (dwRes) { #if defined(_MSC_VER) ans.attachment1 = GetErrorMessage(ans.attachment2, "执行文件操作失败。"); Dbg("ExecuteFile failed: %s", (LPCTSTR)ans.attachment2); #else ans.attachment2 = "不支持该操作"; ans.attachment1 = ans.attachment2.GetLength(); ans.result = OPT_FILE_RES_NOT_SUPPORT; #endif //_MSC_VER } } break; case OPT_FILE_CMD_DELETE: //2 case OPT_FILE_CMD_CLEAR: //3 { bool bClear = !!(ctx->Req.mode == OPT_FILE_CMD_CLEAR); if (!bClear) { Dbg("Delete flag."); } if (type == FT_Unknown) { ans.result = OPT_FILE_RES_INVALID; ans.attachment2 = "所指定的文件不存在。"; ans.attachment1 = ans.attachment2.GetLength(); break; } #if defined(_MSC_VER) if (type == FT_Volume) { if (!bClear) { ans.result = OPT_FILE_RES_INVALID; ans.attachment2 = "该操作对卷类型的文件无效。"; ans.attachment1 = ans.attachment2.GetLength(); } else if (ClearDirRecursiveA(strCurrent)) { ans.result = OPT_FILE_RES_SUCCESS; bNeedToRefleshEntity = true; } else { ans.attachment2 = "清空卷操作执行失败。"; ans.attachment1 = ans.attachment2.GetLength(); ans.result = OPT_FILE_RES_FAILED; } break; } #endif //_MSC_VER if ((type == FT_Directory && ( (!bClear && !RemoveDirRecursiveA(strCurrent)) || (bClear && !ClearDirRecursiveA(strCurrent)) )) || (type == FT_File && !bClear && !RemoveFileA(strCurrent))) { ans.attachment1 = GetErrorMessage(ans.attachment2, ((!bClear) ? "删除操作执行失败。" : "清空操作执行失败。")); Dbg("Delete(%d) or clear file failed: %s", !bClear, ans.attachment2.GetData()); ans.result = OPT_FILE_RES_FAILED; break; } if (type == FT_File && bClear) {//文件内容清理 //simple implement FILE* stream; SetLastError(0); if ((stream = fopen(strCurrent, "w+")) == NULL) { ans.attachment1 = GetErrorMessage(ans.attachment2, "清空文件内容执行失败。"); ans.result = OPT_FILE_RES_FAILED; break; } if (fclose(stream)) { Dbg("fclose(%s) failed", (LPCTSTR)strCurrent); ans.attachment1 = GetErrorMessage(ans.attachment2, "清空文件内容执行失败。"); ans.result = OPT_FILE_RES_FAILED; break; } } ans.result = OPT_FILE_RES_SUCCESS; bNeedToRefleshEntity = true; if ((!bClear && type != FT_File) || (bClear && type == FT_File)) { updateLevel = 1; } } break; case OPT_FILE_CMD_CREATE: //4 { if ((type == FT_Directory && (req.attribute & 0x10)) || (type == FT_File && !(req.attribute & 0x10)) || type == FT_Volume) { Dbg("Existed file occurs create(%d) ?", type); ans.result = OPT_FILE_RES_FAILED; ans.attachment2 = "目录或文件已存在。"; ans.attachment1 = ans.attachment2.GetLength(); break; } BOOL bRet = FALSE; int depth = GetPathDepth(strCurrent); if (depth <= 0) { Dbg("Invalid file path(%s)", (LPCTSTR)strCurrent); ans.result = OPT_FILE_RES_FAILED; ans.attachment2 = "非法文件路径或名称。"; ans.attachment1 = ans.attachment2.GetLength(); break; } if (req.attribute & 0x10) { Dbg("Start to create directory"); if (!CreateDirA(strCurrent, TRUE)) { ans.attachment1 = GetErrorMessage(ans.attachment2, "新建文件夹失败。"); Dbg("Create directory failed: %s", ans.attachment2.GetData()); ans.result = OPT_FILE_RES_FAILED; break; } } else { #if defined(RVC_OS_WIN) if (depth == 1/*根目录下创建文件*/ || CreateParentDirA(strCurrent, TRUE)) { DWORD dwNewAttr = FILE_ATTRIBUTE_NORMAL/* | req.attribute*/; HANDLE hNewFile = CreateFileA(strCurrent, GENERIC_WRITE, 0, NULL, CREATE_NEW, dwNewAttr, NULL); if (hNewFile == INVALID_HANDLE_VALUE) { ans.attachment1 = GetErrorMessage(ans.attachment2, "创建文件失败。"); Dbg("Create file failed: %s", ans.attachment2.GetData()); ans.result = OPT_FILE_RES_FAILED; break; } if (req.content.GetLength() >= 0) { DWORD dwBytesToWrite = (DWORD)req.content.GetLength(); DWORD dwByteWritten = 0; DWORD dwPos = SetFilePointer(hNewFile, 0, NULL, FILE_END); LockFile(hNewFile, dwPos, 0, dwBytesToWrite, 0); BOOL bRes = WriteFile(hNewFile, req.content.GetData(), dwBytesToWrite, &dwByteWritten, NULL); UnlockFile(hNewFile, dwPos, 0, dwBytesToWrite, 0); if (!bRes || dwByteWritten != dwBytesToWrite) { ans.attachment1 = GetErrorMessage(ans.attachment2, !bRes ? "写入文件操作失败。" : "文件数据写入不完整。"); Dbg("Write file failed: %s", ans.attachment2.GetData()); Dbg("Write file is incompletely(%u/%u)", dwByteWritten, dwBytesToWrite); CloseHandle(hNewFile); DeleteFileA(strCurrent); ans.result = OPT_FILE_RES_FAILED; break; } } CloseHandle(hNewFile); } else { ans.attachment1 = GetErrorMessage(ans.attachment2, "创建目标文件所在目录失败。"); Dbg("Create parent directory failed: %s", (LPCTSTR)ans.attachment2); ans.result = OPT_FILE_RES_FAILED; break; } #else ans.result = OPT_FILE_RES_NOT_SUPPORT; ans.attachment2 = "不支持操作"; ans.attachment1 = ans.attachment2.GetLength(); break; #endif //RVC_OS_WIN } ans.result = OPT_FILE_RES_SUCCESS; bNeedToRefleshEntity = true; updateLevel = 1; } break; case OPT_FILE_CMD_APPEND: //5 #if defined(_MSC_VER) { if (type != FT_File) { Dbg("file is not existed(%d) ?", type); ans.result = OPT_FILE_RES_FAILED; ans.attachment2 = "目标文件不存在或非文件类型。"; ans.attachment1 = ans.attachment2.GetLength(); break; } else if (req.content.GetLength() <= 0) { Dbg("invalid file content %d", req.content.GetLength()); ans.result = OPT_FILE_RES_FAILED; ans.attachment2 = "写入的文件内容不存在。"; ans.attachment1 = ans.attachment2.GetLength(); break; } DWORD dwBytesToWrite = (DWORD)req.content.GetLength(); DWORD dwByteWritten = 0; HANDLE hNewFile = CreateFileA(strCurrent, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, /*OPEN_EXISTING*/OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hNewFile == INVALID_HANDLE_VALUE) { ans.attachment1 = GetErrorMessage(ans.attachment2, "打开文件失败。"); Dbg("open file failed: %s", (LPCTSTR)ans.attachment2); ans.result = OPT_FILE_RES_FAILED; break; } DWORD dwPos = SetFilePointer(hNewFile, 0, NULL, FILE_END); LockFile(hNewFile, dwPos, 0, dwBytesToWrite, 0); BOOL bRes = WriteFile(hNewFile, req.content.GetData(), dwBytesToWrite, &dwByteWritten, NULL); UnlockFile(hNewFile, dwPos, 0, dwBytesToWrite, 0); if (!bRes || dwByteWritten != dwBytesToWrite) { ans.attachment1 = GetErrorMessage(ans.attachment2, !bRes ? "写入文件操作失败。" : "文件数据写入不完整。"); Dbg("Append file failed: %s", ans.attachment2.GetData()); Dbg("Append file is incompletely(%u/%u)", dwByteWritten, dwBytesToWrite); ans.result = OPT_FILE_RES_FAILED; CloseHandle(hNewFile); DeleteFileA(strCurrent); ans.result = OPT_FILE_RES_FAILED; break; } CloseHandle(hNewFile); ans.result = OPT_FILE_RES_SUCCESS; bNeedToRefleshEntity = true; updateLevel = 1; } #else ans.result = OPT_FILE_RES_NOT_SUPPORT; ans.attachment2 = "不支持操作"; ans.attachment1 = ans.attachment2.GetLength(); #endif //_MSC_VER break; case OPT_FILE_CMD_RENAME: //6 { #if defined(_MSC_VER) Dbg("Rename a file ? it would be critical..."); if (type == FT_Unknown || type == FT_Volume) { Dbg("file is not existed(%d)?", type); ans.result = OPT_FILE_RES_FAILED; ans.attachment2 = type == FT_Unknown ? "目标文件不存在。" : "文件类型(卷)不支持当前操作。"; ans.attachment1 = ans.attachment2.GetLength(); break; } req.content = req.content.Trim(); if (req.content.GetLength() <= 0) { Dbg("empty new file name ?"); ans.result = OPT_FILE_RES_FAILED; ans.attachment2 = "传入新文件名参数为空。"; ans.attachment1 = ans.attachment2.GetLength(); break; } if (strchr(req.content, '\\') || strchr(req.content, '/')) { Dbg("invalid new file name: %s", (LPCTSTR)req.content); ans.result = OPT_FILE_RES_FAILED; ans.attachment2 = "新文件名参数无效。"; ans.attachment1 = ans.attachment2.GetLength(); break; } const size_t st_len = nCurLen + req.content.GetLength(); char* path = new char[st_len]; ZeroMemory(path, st_len); int res = 0; if (path == NULL) { res = 1; LogWarn(Severity_Middle, Error_Resource, 0, "alloc path memory failed"); } else { int dir_len = 0; CSimpleStringA strNewName = req.content; if ((dir_len = GetDirSplitPath(strCurrent, 1, path, st_len)) > 0) { if (!req.attribute && type == FT_File) { Dbg("save file-type suffix in rename mode."); char tmp[MAX_PATH] = { 0 }; strcpy(tmp, strCurrent.GetData() + dir_len + 1); char* pos = strrchr(tmp, '.'); if (pos) { strNewName += pos; } } strcat(path, SPLIT_SLASH_STR); strcat(path, strNewName); res = rename(strCurrent, path); } else { Dbg("GetDirSplitPath failed: %s vs %s", (LPCTSTR)strCurrent, path); res = 1; } delete[] path; path = NULL; } if (res) { Dbg("rename failed: %d", errno); ans.result = OPT_FILE_RES_FAILED; ans.attachment2 = "重命名操作失败。"; ans.attachment1 = ans.attachment2.GetLength(); break; } ans.result = OPT_FILE_RES_SUCCESS; bNeedToRefleshEntity = true; updateLevel = 1; #else ans.result = OPT_FILE_RES_NOT_SUPPORT; ans.attachment2 = "不支持操作"; ans.attachment1 = ans.attachment2.GetLength(); #endif //_MSC_VER } break; default: { LogWarn(Severity_Low, Error_Unexpect, 0, CSimpleStringA::Format("Unexpected file operation command : %d", ctx->Req.mode)); CSimpleStringA strTip = CSimpleStringA::Format("无法识别的操作指令(mode: %d)。", ctx->Req.mode); ans.attachment1 = strTip.GetLength(); ans.attachment2 = strTip; } break; } if (ans.result == OPT_FILE_RES_SUCCESS) { if (bNeedToSetCtxEntities || bNeedToRefleshEntity) { bool bReInit = true; if (bNeedToRefleshEntity) { DWORD dwCnt = 0; CSimpleStringA strHeader = strCurrent; if (updateLevel != 0) { char* pPath = new char[nCurLen + 1]; if (pPath == NULL) bReInit = false; else { UINT uRes = GetDirSplitPath(strHeader, updateLevel, pPath, nCurLen + 1); if (uRes == 0) bReInit = false; strHeader = pPath; delete[] pPath; pPath = NULL; } } if (bReInit) { bReInit = !!InitialDirectoryEntity(strHeader, dwCnt); } bNeedToRefleshHeader = true; } if (bReInit) { ConveyFileEntityToContext(ctx, bNeedToRefleshHeader); } } } else { Dbg("attach1: %d", ans.attachment1); Dbg("attach2: %s", ans.attachment2.GetData()); } ctx->Answer(Error_Succeed); return (ans.result); } DWORD ResourceWatcherFSM::ExecuteFile(LPCTSTR lpszFilePath, LPCTSTR lpParam) { DWORD dwRes = 0; #if defined(_MSC_VER) SHELLEXECUTEINFOA shell; memset(&shell, 0, sizeof(SHELLEXECUTEINFOA)); shell.cbSize = sizeof(SHELLEXECUTEINFOA); shell.lpFile = lpszFilePath; shell.lpParameters = lpParam; shell.fMask = SEE_MASK_INVOKEIDLIST; shell.lpVerb = NULL; shell.nShow = SW_SHOWDEFAULT; if (!ShellExecuteExA(&shell)) { dwRes = GetLastError(); int nRes = (int)shell.hInstApp; Dbg("GLE=%u, InstApp=%d", dwRes, nRes); switch (dwRes) { case ERROR_NO_ACE_CONDITION: LogWarn(Severity_Middle, Error_MethodNotFound, dwRes, CSimpleStringA::Format("Target file(%s) association not available !", lpszFilePath)); break; case ERROR_ACCESS_DENIED: LogWarn(Severity_Middle, Error_NoPrivilege, dwRes, CSimpleStringA::Format("Target file(%s) not privilege !", lpszFilePath)); break; case ERROR_PATH_NOT_FOUND: case ERROR_FILE_NOT_FOUND: LogWarn(Severity_Middle, Error_NotExist, dwRes, CSimpleStringA::Format("Target file(%s) not existed !", lpszFilePath)); break; case ERROR_DLL_NOT_FOUND: LogWarn(Severity_Middle, Error_NotExist, dwRes, CSimpleStringA::Format("One of library file for Target(%s) not existed !", lpszFilePath)); break; case ERROR_NOT_ENOUGH_MEMORY: LogWarn(Severity_Middle, Error_Resource, dwRes, CSimpleStringA::Format("Not enough memory for Target(%s) to perform !", lpszFilePath)); break; case ERROR_SHARING_VIOLATION: LogWarn(Severity_Middle, Error_Overflow, dwRes, CSimpleStringA::Format("Violation occurred for Target(%s) to share !", lpszFilePath)); break; default: LogWarn(Severity_Middle, Error_Unexpect, dwRes, CSimpleStringA::Format("Unpected condtion for Target(%s) to execute(%u) !" , lpszFilePath, dwRes)); break; } } #else dwRes = 1; #endif //_MSC_VER return dwRes; } BOOL ResourceWatcherFSM::ConveyFileEntityToContext(const SpReqAnsContext::Pointer & ctx , BOOL bRefleshHeader /*= FALSE*/, DWORD dwFilterAttributes) { if (ctx == NULL) return FALSE; #if defined(_MSC_VER) ULARGE_INTEGER ilOffsetSize; ilOffsetSize.QuadPart = 0; const DWORD dwBufSize = m_FileEntry.FileNamesBuffer.GetCount(); DWORD dwInheritForbidAttrs = 0UL; if (bRefleshHeader) { if (m_FileEntry.Current.mNameLength != 0) { ilOffsetSize.LowPart = m_FileEntry.Current.mNameOffset; ilOffsetSize.HighPart = m_FileEntry.Current.mNameLength; GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, ctx->Ans.header, &ilOffsetSize); ctx->Ans.fileAttribute = m_FileEntry.Current.mAttributes; ctx->Ans.ftAccess = m_FileEntry.Current.mftAccess; ctx->Ans.ftModified = m_FileEntry.Current.mftModified; ctx->Ans.ftCreate = m_FileEntry.Current.mftCreate; ctx->Ans.fileSize = m_FileEntry.Current.mFileSize; if (!ctx->Ans.header.IsNullOrEmpty() && ctx->Ans.header.GetLength() > 0) { if (InBlackListOrNot(ctx->Ans.header, OPT_FILE_CMD_DELETE)) { dwInheritForbidAttrs |= BS_DENY_DELETE; Dbg("header-forbit:%s", ctx->Ans.header.GetData()); } } } } int count = m_FileEntry.SubFiles.GetCount(); int minusCount = 0; for (int i = 0; i < count; ++i) if (m_FileEntry.SubFiles[i].mAttributes & dwFilterAttributes) minusCount++; count = count - minusCount; ctx->Ans.count = count; if (count > 0) { if (count >= MAX_SUBFILES_COUNT) { Dbg("Exceedingly max file count: %d >= %d", count, MAX_SUBFILES_COUNT); std::vector vtFileShells; for (int i = 0; i < count; ++i) { CSimpleFileShell item = RetriveSubFile(&m_FileEntry, i); vtFileShells.push_back(item); } sort(vtFileShells.begin(), vtFileShells.end(), _CompareFunc); char szFormat[128] = { 0 }; count = MAX_SUBFILES_COUNT; ctx->Ans.count = count; ctx->Ans.fileAttributes.Init(count); ctx->Ans.fileNames.Init(count); ctx->Ans.ftCreates.Init(count); ctx->Ans.ftModifieds.Init(count); ctx->Ans.ftAccesses.Init(count); ctx->Ans.fileSizes.Init(count); ctx->Ans.forbidAttributes.Init(count); ctx->Ans.reserved1.Init(count); ctx->Ans.reserved2.Init(count); for (int i = 0; i < count; ++i) { CSimpleFileComponent* component = (CSimpleFileComponent*)vtFileShells[i]; ilOffsetSize.LowPart = component->mNameOffset; ilOffsetSize.HighPart = component->mNameLength; if (component->mAttributes & dwFilterAttributes) { CSimpleStringA strFileName; GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, strFileName, &ilOffsetSize); Dbg("%s reserved: 0x%X", strFileName.GetData(), component->mAttributes); continue; } ctx->Ans.reserved1[i] = 0; ctx->Ans.reserved2[i] = ""; ctx->Ans.fileAttributes[i] = component->mAttributes; ctx->Ans.ftCreates[i] = component->mftCreate; ctx->Ans.ftModifieds[i] = component->mftModified; ctx->Ans.ftAccesses[i] = component->mftAccess; ctx->Ans.fileSizes[i] = component->mFileSize; //TODO: Need to judge whether need to calculate size of directory. GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, ctx->Ans.fileNames[i], &ilOffsetSize); Dbg("ADD %d: %s", __LINE__, ctx->Ans.fileNames[i].GetData()); ctx->Ans.forbidAttributes[i] = 0; if (m_FileEntry.Current.mNameLength == 0 && ctx->Ans.fileAttributes[i] == 0) { ctx->Ans.forbidAttributes[i] |= BS_DENY_DELETE; } else if (!ctx->Ans.fileNames[i].IsNullOrEmpty()) { CSimpleStringA csFilePath; GetFullFilePath(&m_FileEntry, i, csFilePath); if (InBlackListOrNot(csFilePath, OPT_FILE_CMD_DELETE)) { ctx->Ans.forbidAttributes[i] |= BS_DENY_DELETE; Dbg("fobbitten FullPath: %s", (LPCTSTR)csFilePath); } } } vtFileShells.clear(); } else { ctx->Ans.fileAttributes.Init(count); ctx->Ans.fileNames.Init(count); ctx->Ans.ftCreates.Init(count); ctx->Ans.ftModifieds.Init(count); ctx->Ans.ftAccesses.Init(count); ctx->Ans.fileSizes.Init(count); ctx->Ans.forbidAttributes.Init(count); ctx->Ans.reserved1.Init(count); ctx->Ans.reserved2.Init(count); for (int i = 0; i < count; ++i) { ilOffsetSize.LowPart = m_FileEntry.SubFiles[i].mNameOffset; ilOffsetSize.HighPart = m_FileEntry.SubFiles[i].mNameLength; if (m_FileEntry.SubFiles[i].mAttributes & dwFilterAttributes) { CSimpleStringA strFileName; GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, strFileName, &ilOffsetSize); Dbg("%s reserved: 0x%X", strFileName.GetData(), m_FileEntry.SubFiles[i].mAttributes); continue; } ctx->Ans.reserved1[i] = 0; ctx->Ans.reserved2[i] = ""; ctx->Ans.fileAttributes[i] = m_FileEntry.SubFiles[i].mAttributes; ctx->Ans.ftCreates[i] = m_FileEntry.SubFiles[i].mftCreate; ctx->Ans.ftModifieds[i] = m_FileEntry.SubFiles[i].mftModified; ctx->Ans.ftAccesses[i] = m_FileEntry.SubFiles[i].mftAccess; ctx->Ans.fileSizes[i] = m_FileEntry.SubFiles[i].mFileSize; //TODO: Need to judge whether need to calculate size of directory. GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, ctx->Ans.fileNames[i], &ilOffsetSize); ctx->Ans.forbidAttributes[i] = 0; Dbg("ADD %d: %s", __LINE__, ctx->Ans.fileNames[i].GetData()); if (m_FileEntry.Current.mNameLength == 0 && ctx->Ans.fileAttributes[i] == 0) { ctx->Ans.forbidAttributes[i] |= BS_DENY_DELETE; } else if (!ctx->Ans.fileNames[i].IsNullOrEmpty()) { CSimpleStringA csFilePath; GetFullFilePath(&m_FileEntry, i, csFilePath); if (InBlackListOrNot(csFilePath, OPT_FILE_CMD_DELETE)) { ctx->Ans.forbidAttributes[i] |= BS_DENY_DELETE; Dbg("fobbitten FullPath: %s", (LPCTSTR)csFilePath); } } } } } #else ULARGE_INTEGER ilOffsetSize; ilOffsetSize.QuadPart = 0; const DWORD dwBufSize = m_FileEntry.FileNamesBuffer.GetCount(); DWORD dwInheritForbidAttrs = 0UL; if (bRefleshHeader) { if (m_FileEntry.Current.mNameLength != 0) { ilOffsetSize.u.LowPart = m_FileEntry.Current.mNameOffset; ilOffsetSize.u.HighPart = m_FileEntry.Current.mNameLength; GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, ctx->Ans.header, &ilOffsetSize); ctx->Ans.fileAttribute = m_FileEntry.Current.mAttributes; ctx->Ans.ftAccess = m_FileEntry.Current.mftAccess; ctx->Ans.ftModified = m_FileEntry.Current.mftModified; ctx->Ans.ftCreate = m_FileEntry.Current.mftCreate; ctx->Ans.fileSize = m_FileEntry.Current.mFileSize; if (!ctx->Ans.header.IsNullOrEmpty()) { if (InBlackListOrNot(ctx->Ans.header, OPT_FILE_CMD_DELETE)) { dwInheritForbidAttrs |= BS_DENY_DELETE; Dbg("header-forbit:%s", ctx->Ans.header.GetData()); } } } } int count = m_FileEntry.SubFiles.GetCount(); int minusCount = 0; for (int i = 0; i < count; ++i) if (m_FileEntry.SubFiles[i].mAttributes & dwFilterAttributes) minusCount++; count = count - minusCount; ctx->Ans.count = count; if (count > 0) { if (count >= MAX_SUBFILES_COUNT) { Dbg("Exceedingly max file count: %d >= %d", count, MAX_SUBFILES_COUNT); std::vector vtFileShells; for (int i = 0; i < count; ++i) { CSimpleFileShell item = RetriveSubFile(&m_FileEntry, i); vtFileShells.push_back(item); } sort(vtFileShells.begin(), vtFileShells.end(), _CompareFunc); char szFormat[128] = { 0 }; count = MAX_SUBFILES_COUNT; ctx->Ans.count = count; ctx->Ans.reserved1.Init(count); ctx->Ans.reserved2.Init(count); ctx->Ans.fileAttributes.Init(count); ctx->Ans.fileNames.Init(count); ctx->Ans.ftCreates.Init(count); ctx->Ans.ftModifieds.Init(count); ctx->Ans.ftAccesses.Init(count); ctx->Ans.fileSizes.Init(count); ctx->Ans.forbidAttributes.Init(count); for (int i = 0; i < count; ++i) { CSimpleFileComponent* component = (CSimpleFileComponent*)vtFileShells[i]; ilOffsetSize.u.LowPart = component->mNameOffset; ilOffsetSize.u.HighPart = component->mNameLength; if (component->mAttributes & dwFilterAttributes) { CSimpleStringA strFileName; GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, strFileName, &ilOffsetSize); Dbg("%s reserved: 0x%X", strFileName.GetData(), component->mAttributes); continue; } ctx->Ans.reserved1[i] = 0; ctx->Ans.reserved2[i] = ""; ctx->Ans.fileAttributes[i] = component->mAttributes; ctx->Ans.ftCreates[i] = component->mftCreate; ctx->Ans.ftModifieds[i] = component->mftModified; ctx->Ans.ftAccesses[i] = component->mftAccess; ctx->Ans.fileSizes[i] = component->mFileSize; //TODO: Need to judge whether need to calculate size of directory. GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, ctx->Ans.fileNames[i], &ilOffsetSize); ctx->Ans.forbidAttributes[i] = 0; Dbg("ADD %d: %s", __LINE__, ctx->Ans.fileNames[i].GetData()); if (m_FileEntry.Current.mNameLength == 0 && ctx->Ans.fileAttributes[i] == 0) { ctx->Ans.forbidAttributes[i] |= BS_DENY_DELETE; } else if (!ctx->Ans.fileNames[i].IsNullOrEmpty()) { CSimpleStringA csFilePath; GetFullFilePath(&m_FileEntry, i, csFilePath); if (InBlackListOrNot(csFilePath, OPT_FILE_CMD_DELETE)) { ctx->Ans.forbidAttributes[i] |= BS_DENY_DELETE; Dbg("fobbitten FullPath: %s", (LPCTSTR)csFilePath); } } } vtFileShells.clear(); } else { ctx->Ans.fileAttributes.Init(count); ctx->Ans.fileNames.Init(count); ctx->Ans.ftCreates.Init(count); ctx->Ans.ftModifieds.Init(count); ctx->Ans.ftAccesses.Init(count); ctx->Ans.fileSizes.Init(count); ctx->Ans.forbidAttributes.Init(count); ctx->Ans.reserved1.Init(count); ctx->Ans.reserved2.Init(count); for (int i = 0; i < count; ++i) { ilOffsetSize.u.LowPart = m_FileEntry.SubFiles[i].mNameOffset; ilOffsetSize.u.HighPart = m_FileEntry.SubFiles[i].mNameLength; if (m_FileEntry.SubFiles[i].mAttributes & dwFilterAttributes) { CSimpleStringA strFileName; GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, strFileName, &ilOffsetSize); Dbg("%s reserved: 0x%X", strFileName.GetData(), m_FileEntry.SubFiles[i].mAttributes); continue; } ctx->Ans.reserved1[i] = 0; ctx->Ans.reserved2[i] = ""; ctx->Ans.fileAttributes[i] = m_FileEntry.SubFiles[i].mAttributes; ctx->Ans.ftCreates[i] = m_FileEntry.SubFiles[i].mftCreate; ctx->Ans.ftModifieds[i] = m_FileEntry.SubFiles[i].mftModified; ctx->Ans.ftAccesses[i] = m_FileEntry.SubFiles[i].mftAccess; ctx->Ans.fileSizes[i] = m_FileEntry.SubFiles[i].mFileSize; //TODO: Need to judge whether need to calculate size of directory. GetSubFileName(m_FileEntry.FileNamesBuffer, dwBufSize, ctx->Ans.fileNames[i], &ilOffsetSize); ctx->Ans.forbidAttributes[i] = 0; Dbg("ADD %d: %s", __LINE__, ctx->Ans.fileNames[i].GetData()); if (m_FileEntry.Current.mNameLength == 0 && ctx->Ans.fileAttributes[i] == 0) { ctx->Ans.forbidAttributes[i] |= BS_DENY_DELETE; } else if (!ctx->Ans.fileNames[i].IsNullOrEmpty()) { CSimpleStringA csFilePath; GetFullFilePath(&m_FileEntry, i, csFilePath); if (InBlackListOrNot(csFilePath, OPT_FILE_CMD_DELETE)) { ctx->Ans.forbidAttributes[i] |= BS_DENY_DELETE; Dbg("fobbitten FullPath: %s", (LPCTSTR)csFilePath); } } } } } #endif //_MSC_VER //Free action for saving memory. m_FileEntry.SubFiles.Clear(); m_FileEntry.FileNamesBuffer.Clear(); m_FileEntry.Current.Clear(); return TRUE; } int ResourceWatcherFSM::FilterFilePathAhead(LPCTSTR lpszPath, const int option) { #if defined(RVC_OS_WIN) size_t len = strlen(lpszPath); if (!((lpszPath[0] <= 'z' && lpszPath[0] >= 'a') || (lpszPath[0] <= 'Z' && lpszPath[0] >= 'A')) || lpszPath[1] != ':') { Dbg("illegal disk format path !"); return -2; } const char disk = lpszPath[0]; if (disk >= 'a' && disk <= 'z') disk -= 32; if (!sBDiskValStatus[int(disk - 'A')]) { Dbg("Specified disk(%c) not existed", disk); return -3; } char* path = new char[len + 1]; LOG_ASSERT(path != NULL); memset(path, 0, sizeof(char) * (len + 1)); memcpy(path, lpszPath, len); path[len] = '\0'; int pos = len - 1; for (; pos >= 0 && (path[pos] == '\\' || path[pos] == '/'); --pos) { ;// } path[pos + 1] = '\0'; len = strlen(path); if (len <= 1) { delete[] path; return -1; } else if (len == 2 && option == OPT_FILE_CMD_DELETE) { /*disk volumn to delete*/ delete[] path; return 1; } if (InBlackListOrNot(path, option)) { delete[] path; return 2; } delete[] path; return 0; #else size_t len = strlen(lpszPath); if (lpszPath[0] != '/') { Dbg("illegal disk format path !"); return -2; } char* path = new char[len + 1]; LOG_ASSERT(path != NULL); memset(path, 0, sizeof(char) * (len + 1)); memcpy(path, lpszPath, len); path[len] = '\0'; int pos = len - 1; for (; pos >= 0 && (path[pos] == '\\' || path[pos] == '/'); --pos) { ;// } path[pos + 1] = '\0'; len = strlen(path); if (len < 1) { delete[] path; return -1; } else if (len == 1 && option == OPT_FILE_CMD_DELETE) { /*disk volumn to delete*/ delete[] path; return 1; } if (InBlackListOrNot(path, option)) { delete[] path; return 2; } delete[] path; return 0; #endif //RVC_OS_WIN } BOOL ResourceWatcherFSM::InBlackListOrNot(LPCTSTR lpszPath, const int option) { BOOL bForbidden = FALSE; LOG_ASSERT(lpszPath != NULL && strlen(lpszPath) != 0); DWORD dwRequredAttr = 0; switch (option) { case OPT_FILE_CMD_SPREAD: dwRequredAttr |= BS_DENY_READ; break; case OPT_FILE_CMD_EXECUTE: dwRequredAttr |= BS_DENY_EXECUTE; break; case OPT_FILE_CMD_CREATE: dwRequredAttr |= BS_DENY_CREATE; break; case OPT_FILE_CMD_DELETE: case OPT_FILE_CMD_CLEAR: case OPT_FILE_CMD_RENAME: dwRequredAttr |= BS_DENY_DELETE; break; case OPT_FILE_CMD_APPEND: dwRequredAttr |= BS_DENY_MODIFY; break; default: Dbg("Unexpcted option: %d, allow it determined by later process.", option); return bForbidden; break; } const size_t len = strlen(lpszPath); char* temp_path = new char[len + 1]; if (temp_path == NULL) { Dbg("new temp_path failed"); return bForbidden; } memset(temp_path, 0, sizeof(char) * (len + 1)); strcpy_s(temp_path, len + 1, lpszPath); for (size_t i = 0; i < len; ++i) { #if defined(_MSC_VER) if (temp_path[i] == '/') temp_path[i] = '\\'; #else if (temp_path[i] == '\\') temp_path[i] = '/'; #endif //_MSC_VER } lpszPath = temp_path; for (const_bs_iter cit = m_forbidDirList.cbegin(); cit != m_forbidDirList.cend() && !bForbidden; ++cit) { const bs_key& path = cit->first; const bs_value& resist = cit->second; const size_t n = strlen(path.c_str()); if (dwRequredAttr & resist) { if (path[0] == '*') { bForbidden = TRUE; Dbg("Forbit0"); break; } if (!_strnicmp(lpszPath, path.c_str(), min(len, n))) { if (len > n && (lpszPath[n] == '\\' || lpszPath[n] == '/') && (resist & BS_DENY_INHERITED)) { bForbidden = TRUE; Dbg("forbit1"); } if (len == n) { bForbidden = TRUE; Dbg("forbit2"); } if (len < n) { FileType ft; if (IsPathExisted(path.c_str(), ft)) { bForbidden = TRUE; Dbg("forbit3"); } } } } } if (temp_path) { delete[] temp_path; temp_path = NULL; } return bForbidden; } void ResourceWatcherFSM::InitBlackList() { LOG_FUNCTION(); m_forbidDirList.clear(); DWORD dwDenyAttr; #if defined(_MSC_VER) const int INFO_BUFFER_SIZE = MAX_PATH; char infoBuf[INFO_BUFFER_SIZE]; DWORD bufCharCount = INFO_BUFFER_SIZE; char sys_disk = '\0'; bufCharCount = INFO_BUFFER_SIZE; if (!GetComputerName(infoBuf, &bufCharCount)) Dbg("GetComputerName failed, GLE=%u", GetLastError()); else Dbg("Computer name: %s", infoBuf); // Get and display the user name. ZeroMemory(infoBuf, INFO_BUFFER_SIZE); bufCharCount = INFO_BUFFER_SIZE; if (!GetUserName(infoBuf, &bufCharCount)) Dbg("GetUserName failed, GLE=%u", GetLastError()); else Dbg("User name: %s", infoBuf); // All file cannot be executed !! -Josephus@2017612 9:29:01 ZeroMemory(infoBuf, INFO_BUFFER_SIZE); infoBuf[0] = '*', infoBuf[1] = '\0'; dwDenyAttr = BS_DENY_EXECUTE | BS_DENY_INHERITED; Dbg("Add All file filter: %s - 0x%X", infoBuf, dwDenyAttr); m_forbidDirList.insert(BlackSheetPair(string(infoBuf), dwDenyAttr)); // Get and display the system directory. ZeroMemory(infoBuf, INFO_BUFFER_SIZE); if (!GetSystemDirectory(infoBuf, INFO_BUFFER_SIZE)) { Dbg("GetSystemDirectory failed, GLE=%u", GetLastError()); } else { dwDenyAttr = BS_DENY_DELETE/* | BS_DENY_EXECUTE*/ | BS_DENY_INHERITED; Dbg("Add System Directory: %s - 0x%X", infoBuf, dwDenyAttr); m_forbidDirList.insert(BlackSheetPair(string(infoBuf), dwDenyAttr)); sys_disk = infoBuf[0]; if (sys_disk >= 'a' && sys_disk <= 'z') sys_disk -= 32; int diskNo = sys_disk - 'A'; LOG_ASSERT(sBDiskValStatus[diskNo]); sBDiskValStatus[diskNo] = sBDiskValStatus[diskNo] + 2; //Set system disk flag } // Get and display the Windows directory. ZeroMemory(infoBuf, INFO_BUFFER_SIZE); if (!GetWindowsDirectory(infoBuf, INFO_BUFFER_SIZE)) { Dbg("GetWindowsDirectory failed, GLE=%u", GetLastError()); } else { dwDenyAttr = BS_DENY_DELETE/* | BS_DENY_EXECUTE*/ | BS_DENY_INHERITED; Dbg("Add Windows Directory: %s - 0x%X", infoBuf, dwDenyAttr); m_forbidDirList.insert(BlackSheetPair(string(infoBuf), dwDenyAttr)); } if (sys_disk != '\0') { ZeroMemory(infoBuf, INFO_BUFFER_SIZE); ////////////////////////////////////////////////////////////////////////// LOG_ASSERT(INFO_BUFFER_SIZE > 4); infoBuf[0] = sys_disk; infoBuf[1] = ':'; infoBuf[2] = '\\'; infoBuf[3] = '\0'; Dbg("Start to Add system limited path: %d", LIMITED_SYS_COUNT); const DWORD dwSysAttr = BS_DENY_DELETE/* | BS_DENY_EXECUTE*/ | BS_DENY_INHERITED; for (int i = 0; i < LIMITED_SYS_COUNT; ++i) { string strfullPath = infoBuf; strfullPath += LIMITED_SYS_PATH(i); if (m_forbidDirList.find(strfullPath) == m_forbidDirList.end()) { Dbg("Add %s - 0x%X", strfullPath.c_str(), dwSysAttr); m_forbidDirList[strfullPath] = dwSysAttr; } } } #endif //_MSC_VER ////////////////////////////////////////////////////////////////////////// CSimpleStringA strPath; if (GetEntityBase()->GetFunction()->GetPath("UploadVideo", strPath) == Error_Succeed) { dwDenyAttr = BS_DENY_DELETE | BS_DENY_INHERITED; Dbg("Add %s - 0x%X", (LPCTSTR)strPath, dwDenyAttr); m_forbidDirList[string(strPath.GetData())] = dwDenyAttr; } Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); if (GetEntityBase()->GetFunction()->GetPath("UploadPhoto", strPath) == Error_Succeed) { dwDenyAttr = BS_DENY_DELETE | BS_DENY_INHERITED; Dbg("Add %s - 0x%X", (LPCTSTR)strPath, dwDenyAttr); m_forbidDirList[string(strPath.GetData())] = dwDenyAttr; } Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); if (GetEntityBase()->GetFunction()->GetPath("Cfg", strPath) == Error_Succeed) { dwDenyAttr = BS_DENY_DELETE | BS_DENY_INHERITED; Dbg("Add %s - 0x%X", (LPCTSTR)strPath, dwDenyAttr); m_forbidDirList[string(strPath.GetData())] = dwDenyAttr; } Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); if (GetEntityBase()->GetFunction()->GetPath("Dep", strPath) == Error_Succeed) { dwDenyAttr = BS_DENY_DELETE | BS_DENY_CREATE | BS_DENY_MODIFY | BS_DENY_INHERITED; Dbg("Add %s - 0x%X", (LPCTSTR)strPath, dwDenyAttr); m_forbidDirList[string(strPath.GetData())] = dwDenyAttr; } Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); if (GetEntityBase()->GetFunction()->GetPath("Base", strPath) == Error_Succeed) { Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); dwDenyAttr = BS_DENY_DELETE | BS_DENY_EXECUTE | BS_DENY_INHERITED; const size_t len = strPath.GetLength(); char* path = new char[len + 1]; //Run Directory if (path && (ZeroMemory(path, len + 1), GetDirSplitPath(strPath, 2, path, len + 1) > 0)) { //Dbg("Add %s - 0x%X", path, dwDenyAttr); //m_forbidDirList[string(path)] = dwDenyAttr; } if (path) { strPath = path; delete[] path; } CSimpleStringA strPathInner; Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); strPathInner = strPath + SPLIT_SLASH_STR + "hardwarecfg"; dwDenyAttr = BS_DENY_DELETE | BS_DENY_MODIFY | BS_DENY_INHERITED; Dbg("Add %s - 0x%X", (LPCTSTR)strPathInner, dwDenyAttr); m_forbidDirList[string(strPathInner.GetData())] = dwDenyAttr; Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); strPathInner = strPath + SPLIT_SLASH_STR + "runinfo" + SPLIT_SLASH_STR + "kmc"; dwDenyAttr = BS_DENY_DELETE | BS_DENY_INHERITED; Dbg("Add %s - 0x%X", (LPCTSTR)strPathInner, dwDenyAttr); m_forbidDirList[string(strPathInner.GetData())] = dwDenyAttr; Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); strPathInner = strPath + SPLIT_SLASH_STR + "version"; dwDenyAttr = BS_DENY_DELETE | BS_DENY_INHERITED; Dbg("Add %s - 0x%X", (LPCTSTR)strPathInner, dwDenyAttr); m_forbidDirList[string(strPathInner.GetData())] = dwDenyAttr; Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); dwDenyAttr = BS_DENY_MODIFY; strPathInner = strPath + SPLIT_SLASH_STR + "version" + SPLIT_SLASH_STR + "active.txt"; Dbg("Add %s - 0x%X", (LPCTSTR)strPathInner, dwDenyAttr); m_forbidDirList[string(strPathInner.GetData())] = dwDenyAttr; } Dbg("ran at: %s::%d", __FUNCTION__, __LINE__); } #if defined(RVC_OS_WIN) BOOL ResourceWatcherFSM::RetrieveSpecificedEventLogs(const LPEVENTLOGPARAM pEvtLogFilter, LPCTSTR lpszEvtFileName, DWORD & dwEntries) { LOG_FUNCTION(); CEventLog* pEvtLog = NULL; if (pEvtLogFilter->fApplication) { pEvtLog = new CEventLog(APPLICATION_LOG); } else if (pEvtLogFilter->fSystem) { pEvtLog = new CEventLog(SYSTEM_LOG); } else if (pEvtLogFilter->fSecurity) { pEvtLog = new CEventLog(SECURITY_LOG); #ifdef WIDE_CONDITION } else if (pEvtLogFilter->fCustom && wcslen(pEvtLogFilter->lpszCustomEventName) > 0) { #else } else if (pEvtLogFilter->fCustom && strlen(pEvtLogFilter->lpszCustomEventName) > 0) { #endif pEvtLog = new CEventLog(pEvtLogFilter->lpszCustomEventName, TRUE); } if (pEvtLog == NULL || !pEvtLog->IsInitialized()) { if (pEvtLog) delete pEvtLog; return FALSE; } #ifdef WIDE_CONDITION CSimpleStringW strwFileName = CSimpleStringA2W(CSimpleStringA(lpszEvtFileName)); pEvtLog->InitializeLogFile(std::wstring(strwFileName)); #else pEvtLog->InitializeLogFile(std::string(lpszEvtFileName)); #endif dwEntries = pEvtLog->FilterEventLog(pEvtLogFilter->lpszSourceEventName , pEvtLogFilter->wEventType , pEvtLogFilter->dwEventId , pEvtLogFilter->dwTimeBegin , pEvtLogFilter->dwTimeEnd); if (pEvtLog) delete pEvtLog; return TRUE; } DWORD ResourceWatcherFSM::GetEventLog(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); DWORD dwEntries = 0; CHAR szEvtFile[MAX_PATH] = { 0 }; memset(szEvtFile, 0, sizeof(CHAR) * MAX_PATH); if (!CombineTheEvtxFileName(m_strTerminalNo, szEvtFile)) { ctx->Ans.entries = 0; ctx->Ans.information = "初始化事件日志文件名失败"; ctx->Answer(Error_Succeed); if (ExistsFileA(szEvtFile)) { Dbg("Remove file(%s) returned: %d", szEvtFile, RemoveFileA(szEvtFile)); } return 0; } EVENTLOGPARAM filterParam = { 0 }; filterParam.wEventType = ctx->Req.evtLevel == 0x00FF ? 0 : ctx->Req.evtLevel; BOOL bResult = TRUE; DWORD dwResult = ERROR_SUCCESS; Dbg("duration: 0x04X", ctx->Req.duration); if (ctx->Req.duration == DURAITON_CUSTOM) { ULONGLONG ullStart = ctx->Req.startTime; ULONGLONG ullEnd = ctx->Req.endTime; dwResult = CalSpecifiedSecondsFrom1970(ctx->Req.duration, &(filterParam.dwTimeBegin), &(filterParam.dwTimeEnd), &ullStart, &ullEnd); } else { dwResult = CalSpecifiedSecondsFrom1970(ctx->Req.duration, &(filterParam.dwTimeBegin), &(filterParam.dwTimeEnd), NULL, NULL); } if (dwResult != ERROR_SUCCESS) { ctx->Ans.entries = 0; ctx->Ans.information = "时间筛选参数错误"; ctx->Answer(Error_Succeed); return 0; } if (!ctx->Req.evtSrcEventName.IsNullOrEmpty()) { #ifdef WIDE_CONDITION CSimpleStringW wSrvEventName = CSimpleStringA2W(ctx->Req.evtSrcEventName); wcscpy_s(filterParam.lpszSourceEventName, wSrvEventName); #else strcpy_s(filterParam.lpszSourceEventName, ctx->Req.evtSrcEventName); #endif } WORD wEventTypeMask = ctx->Req.evtName == 0 ? 0x00FF : ctx->Req.evtName; Dbg("wEventTypeMask : 0x%04X", wEventTypeMask); if ((wEventTypeMask & 0x0001) == 0x0001) { DWORD dwRes = 0; filterParam.fApplication = TRUE; bResult = RetrieveSpecificedEventLogs(&filterParam, szEvtFile, dwRes); Dbg("[%s]Retrieve application event log returned: %u", bResult ? "Success" : "Failed", dwRes); if (bResult) { dwEntries += dwRes; } filterParam.fApplication = FALSE; } if ((wEventTypeMask & 0x0002) == 0x0002) { DWORD dwRes = 0; filterParam.fSecurity = TRUE; bResult = RetrieveSpecificedEventLogs(&filterParam, szEvtFile, dwRes); Dbg("[%s]Retrieve security event log returned: %u", bResult ? "Success" : "Failed", dwRes); if (bResult) { dwEntries += dwRes; } filterParam.fSecurity = FALSE; } if ((wEventTypeMask & 0x0008) == 0x0008) { DWORD dwRes = 0; filterParam.fSystem = TRUE; bResult = RetrieveSpecificedEventLogs(&filterParam, szEvtFile, dwRes); Dbg("[%s]Retrieve system event log returned: %u", bResult ? "Success" : "Failed", dwRes); if (bResult) { dwEntries += dwRes; } filterParam.fSystem = FALSE; } if ((wEventTypeMask & 0x0100) == 0x0100) { DWORD dwRes = 0; filterParam.fCustom = TRUE; if (!ctx->Req.cusEvtFileName.IsNullOrEmpty()) { #ifdef WIDE_CONDITION CSimpleStringW strwFileName = CSimpleStringA2W(ctx->Req.cusEvtFileName); wcscpy_s(filterParam.lpszCustomEventName, strwFileName); Dbg("Custom event log path: %s", ctx->Req.cusEvtFileName); #else strcpy_s(filterParam.lpszCustomEventName, ctx->Req.cusEvtFileName); Dbg("Custom event log path: %s", filterParam.lpszCustomEventName); #endif } bResult = RetrieveSpecificedEventLogs(&filterParam, szEvtFile, dwRes); Dbg("[%s]Retrieve custom event log returned: %u", bResult ? "Success" : "Failed", dwRes); if (bResult) { dwEntries += dwRes; } filterParam.fCustom = FALSE; } if (dwEntries == 0) { ctx->Ans.entries = 0; LogWarn(Severity_Middle, Error_Unexpect, 0, "The Count of event log is Zero!"); ctx->Ans.information = "未找到相关的系统事件日志"; if (ExistsFileA(szEvtFile)) { Dbg("Remove file(%s) returned: %d", szEvtFile, RemoveFileA(szEvtFile)); } } else { ctx->Ans.entries = dwEntries; ctx->Ans.evtLogFileName = szEvtFile; Dbg("Total count of event log: %u", dwEntries); } ctx->Answer(Error_Succeed); return dwEntries; } DWORD ResourceWatcherFSM::CombineTheEvtxFileName(LPCTSTR lpszTerminalNo, CHAR szEvtxFileName[]) { CSimpleStringA strPath; if (lpszTerminalNo == NULL || strlen(lpszTerminalNo) == 0) { LogError(Severity_Middle, Error_Param, 0, "TerminalNo is nullptr"); return 0; } if (GetEntityBase()->GetFunction()->GetPath("Temp", strPath) != Error_Succeed || strPath.IsNullOrEmpty()) { LogError(Severity_Middle, Error_Unexpect, 0, "GetPath about Temp failed"); return 0; } if (!ExistsDirA(strPath)) { if (!CreateDirRecursiveA(strPath)) { LogError(Severity_Middle, Error_Unexpect, 0, "CreateDirRecursiveA failed"); return 0; } } SYSTEMTIME st, stLocal; GetSystemTime(&st); SystemTimeToTzSpecificLocalTime(NULL, &st, &stLocal); #ifdef WIDE_CONDITION WCHAR fileName[MAX_PATH] = { 0 }; CSimpleStringW strwPath = CSimpleStringA2W(strPath); CSimpleStringW lpwszTerminalNo = CSimpleStringA2W(CSimpleStringA(lpszTerminalNo)); swprintf_s(fileName, L"%ws\\%ws-%d%02d%02d-%02d_%02d_%02d", (LPCWSTR)strwPath, (LPCWSTR)lpwszTerminalNo, stLocal.wYear, stLocal.wMonth, stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond); wcscat_s(fileName, EXT_EVTLOG_NAME); CSimpleStringA lpszFileName = CSimpleStringW2A(CSimpleStringW(fileName)); strcpy_s(szEvtxFileName, MAX_PATH, lpszFileName); Dbg("Combined EventLog FilePah: %s", szEvtxFileName); return strlen(szEvtxFileName); #else CHAR fileName[MAX_PATH] = { 0 }; sprintf_s(fileName, "%s\\%s-%d%02d%02d-%02d_%02d_%02d", (LPCTSTR)strPath, lpszTerminalNo, stLocal.wYear, stLocal.wMonth, stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond); strcat_s(fileName, EXT_EVTLOG_NAME); strcpy_s(szEvtxFileName, MAX_PATH, fileName); Dbg("Combined EventLog FilePah: %s", szEvtxFileName); return strlen(szEvtxFileName); #endif } DWORD ResourceWatcherFSM::CalSpecifiedSecondsFrom1970(const WORD wDuration , DWORD * dwStartTime , DWORD * dwEndTime , const PULONGLONG pStartTime , const PULONGLONG pEndTime) { DWORD status = E_FAIL; if (dwStartTime == NULL || dwEndTime == NULL) return E_INVALIDARG; if (wDuration == DURATION_NONE) { *dwStartTime = *dwEndTime = 0; return ERROR_SUCCESS; } ULONGLONG ullTimeStamp = 0; ULONGLONG SecsTo1970 = 116444736000000000; if (wDuration == DURAITON_CUSTOM) { if (pStartTime == NULL || pEndTime == NULL) return E_POINTER; if (*pStartTime > *pEndTime) return E_INVALIDARG; ullTimeStamp = (*pStartTime) - SecsTo1970; ullTimeStamp /= 10000000ULL; *dwStartTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF); ullTimeStamp = (*pEndTime) - SecsTo1970; ullTimeStamp /= 10000000ULL; *dwEndTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF); return ERROR_SUCCESS; } SYSTEMTIME st; GetSystemTime(&st); FILETIME ftCurTime; GetSystemTimeAsFileTime(&ftCurTime); ULARGE_INTEGER uliCurTime, uliOffset, uliBackTime; uliCurTime.HighPart = ftCurTime.dwHighDateTime; uliCurTime.LowPart = ftCurTime.dwLowDateTime; if (wDuration == DURATION_HOUR_ONE) { uliOffset.QuadPart = UInt32x32To64(1 * 60 * 60, 1e7); uliBackTime.QuadPart = uliCurTime.QuadPart - uliOffset.QuadPart; } else if (wDuration == DURATION_HOUR_TWELVE) { uliOffset.QuadPart = UInt32x32To64(12 * 60 * 60, 1e7); uliBackTime.QuadPart = uliCurTime.QuadPart - uliOffset.QuadPart; } else if (wDuration == DURATION_DAY_ONE) { uliOffset.QuadPart = UInt32x32To64(24 * 60 * 60, 1e7); uliBackTime.QuadPart = uliCurTime.QuadPart - uliOffset.QuadPart; } else if (wDuration == DURATION_DAY_SEVENT) { uliOffset.QuadPart = UInt32x32To64(7 * 24 * 60 * 60, 1e7); uliBackTime.QuadPart = uliCurTime.QuadPart - uliOffset.QuadPart; } else if (wDuration == DURATION_MONTH_ONE) { uliOffset.QuadPart = UInt32x32To64(30 * 24 * 60 * 60, 1e7); uliBackTime.QuadPart = uliCurTime.QuadPart - uliOffset.QuadPart; } else { Dbg("Unexpected duration paramter."); return E_INVALIDARG; } ullTimeStamp = uliBackTime.QuadPart - SecsTo1970; ullTimeStamp /= 10000000ULL; *dwStartTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF); ullTimeStamp = uliCurTime.QuadPart - SecsTo1970; ullTimeStamp /= 10000000ULL; *dwEndTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF); { FILETIME ftBackTime; SYSTEMTIME stUTC, stLocal; ftBackTime.dwHighDateTime = uliBackTime.HighPart; ftBackTime.dwLowDateTime = uliBackTime.LowPart; FileTimeToSystemTime(&ftBackTime, &stUTC); SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); CHAR szTimeFormat[MAX_PATH] = { 0 }; // Build a string showing the date and time. sprintf_s(szTimeFormat, MAX_PATH, "%02d/%02d/%d %02d:%02d:%02d", stLocal.wMonth, stLocal.wDay, stLocal.wYear, stLocal.wHour, stLocal.wMinute, stLocal.wSecond); printf("Start time statmp: %s\n", szTimeFormat); } return ERROR_SUCCESS; } #endif //RVC_OS_WIN BOOL ResourceWatcherFSM::ClearAd0Folder() { LOG_FUNCTION(); CSimpleStringA strAd0Path; CSmartPointer spConfigRun; int nLastTaskTime(0); CSimpleStringA ssFilePath(true); ErrorCodeEnum ec = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); spConfigRun->ReadConfigValueInt("LastClearTime", "Ad0Task", nLastTaskTime); if (IsTodayDone(nLastTaskTime)) { return TRUE; } ec = GetEntityBase()->GetFunction()->GetPath("Ad0", strAd0Path); if (ec != Error_Succeed || strAd0Path.IsNullOrEmpty()) { return FALSE; } if (!ExistsDirA(strAd0Path)) { Dbg("The Folder(%s) is not existed", (LPCTSTR)strAd0Path); spConfigRun->WriteConfigValue("LastClearTime", "Ad0Task", (const char*)CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow())); return TRUE; } Dbg("Ad0Path: %s", (LPCTSTR)strAd0Path); char displayTime[MAX_PATH] = { 0 }; ZeroMemory(&mftAd0RemoveTime, sizeof(FILETIME)); CalculateBackTime(&mftAd0RemoveTime, AD0_DAY_OF_BACKWARD); GetTimeFormatStr(displayTime, MAX_PATH, &mftAd0RemoveTime); Dbg("The date backward to delete: %s", displayTime); #if defined(RVC_OS_WIN) ssFilePath = strAd0Path + "\\*"; #else ssFilePath = strAd0Path; #endif //RVC_OS_WIN int nDelSuc = 0; int nDelFailed = 0; int nfileSum = ClearSpecifieFile(DFT_Ad0, (LPCTSTR)ssFilePath, nDelSuc, nDelFailed); Dbg("#Ad0#There are %d file(s), delete: %d, failed: %d.", nfileSum, nDelSuc, nDelFailed); spConfigRun->WriteConfigValue("LastClearTime", "Ad0Task", (const char*)CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow())); return TRUE; } BOOL ResourceWatcherFSM::IsTodayDone(int nRecordTime) { if (nRecordTime <= 0) { return FALSE; } SYSTEMTIME stNow = {}; SYSTEMTIME stTaskTime = CSmallDateTime(nRecordTime).ToSystemTime(); #if defined(_MSC_VER) GetLocalTime(&stNow); #else stNow = CSmallDateTime::GetNow().ToSystemTime(); #endif //_MSC_VER if (stTaskTime.wYear == stNow.wYear && stTaskTime.wMonth == stNow.wMonth && stTaskTime.wDay == stNow.wDay) { Dbg("task has been executed today, last clear time: %s", (const char*)CSmallDateTime(nRecordTime).ToTimeString()); return TRUE; } else { Dbg("Last record time: %04d-%02d-%02d %02d:%02d:%02d", stTaskTime.wYear, stTaskTime.wMonth, stTaskTime.wDay, stTaskTime.wHour, stTaskTime.wMinute, stTaskTime.wSecond); return FALSE; } } BOOL ResourceWatcherFSM::GetSystemBootTime(CSmallDateTime & systemBootTime) { #if defined(RVC_OS_WIN) PDH_STATUS Status; HQUERY Query = NULL; HCOUNTER hcElapsedTimeCount; BOOL fSuc = FALSE; Status = PdhOpenQuery(NULL, NULL, &Query); PDH_FMT_COUNTERVALUE counterValue; if (Status != ERROR_SUCCESS) { Dbg("PdhOpenQuery failed with status 0x%x.", Status); goto Cleanup; } Status = PdhAddCounter(Query, SystemElapsedQuery, NULL, &hcElapsedTimeCount); if (Status != ERROR_SUCCESS) { Dbg("PdhAddCounter for SystemElapsedQuery failed with status 0x%x.", Status); goto Cleanup; } // 查询性能监视器数据 Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { Dbg("PdhCollectQueryData failed with 0x%x.", Status); goto Cleanup; } Status = PdhGetFormattedCounterValue(hcElapsedTimeCount, PDH_FMT_LARGE, NULL, &counterValue); if (Status == ERROR_SUCCESS) { ULONGLONG ulSinceSeconds = counterValue.largeValue; ULONG days = 0, hours = 0, minutes = 0, seconds = 0; days = ULONG(ulSinceSeconds / DAY_DIV); ulSinceSeconds %= DAY_DIV; hours = ULONG(ulSinceSeconds / HOURS_DIV); ulSinceSeconds %= HOURS_DIV; minutes = ULONG(ulSinceSeconds / MINUS_DIV); ulSinceSeconds %= MINUS_DIV; seconds = ULONG(ulSinceSeconds); Dbg("SystemElapseTime: %u:%02u:%02u:%02u", days, hours, minutes, seconds); FILETIME ftCurTime, ftStartTime; GetSystemTimeAsFileTime(&ftCurTime); ULARGE_INTEGER uliCurTime; uliCurTime.HighPart = ftCurTime.dwHighDateTime; uliCurTime.LowPart = ftCurTime.dwLowDateTime; //Dbg("%I64d", uliCurTime.QuadPart); uliCurTime.QuadPart -= counterValue.largeValue * 1e7; //Dbg("%I64d %I64d", uliCurTime.QuadPart, counterValue.largeValue); ftStartTime.dwHighDateTime = uliCurTime.HighPart; ftStartTime.dwLowDateTime = uliCurTime.LowPart; //Dbg("%d %d %d %d", ftStartTime.dwHighDateTime, ftStartTime.dwLowDateTime, // ftCurTime.dwHighDateTime, ftCurTime.dwLowDateTime); SYSTEMTIME stUTC, stLocal; FileTimeToSystemTime(&ftStartTime, &stUTC); char temp[22]; SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); sprintf_s(temp, 22, "%d-%02d-%02d %02d:%02d:%02d", stLocal.wYear, stLocal.wMonth, stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond); Dbg("OSStartTime: %s", temp); systemBootTime.FromSystemTime(stLocal); fSuc = TRUE; } Cleanup: Status = PdhRemoveCounter(hcElapsedTimeCount); if (Query) { PdhCloseQuery(Query); } return fSuc; #else DWORD ticks = 0; SYSTEMTIME systemTime; struct sysinfo info; time_t curTime = 0; time_t bootTime = 0; struct tm* ptm = NULL; if (sysinfo(&info)) { Dbg("Failed to get sysinfo, errno:%u, reason:%s", errno, strerror(errno)); return FALSE; } time(&curTime); if (curTime > info.uptime) { bootTime = curTime - info.uptime; } else { bootTime = info.uptime - curTime; } ptm = localtime(&bootTime); struct timespec ts; if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts)) ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); systemTime.wYear = (WORD)(ptm->tm_year + 1900); systemTime.wMonth = (WORD)(ptm->tm_mon + 1); systemTime.wDayOfWeek = (WORD)ptm->tm_wday; systemTime.wDay = (WORD)ptm->tm_mday; systemTime.wHour = (WORD)ptm->tm_hour; systemTime.wMinute = (WORD)ptm->tm_min; systemTime.wSecond = (WORD)ptm->tm_sec; systemTime.wMilliseconds = (WORD)(ticks % 1000); systemBootTime.FromSystemTime(systemTime); Dbg("OSStartTime: %s", systemBootTime.ToTimeString().GetData()); return TRUE; #endif //RVC_OS_WIN } #if defined(RVC_OS_WIN) HRESULT ResourceWatcherFSM::SetDefaultAudioPlaybackDevice(LPCWSTR devID) { IPolicyConfigVista* pPolicyConfig; ERole reserved = eConsole; HRESULT hr = CoCreateInstance(__uuidof(CPolicyConfigVistaClient), NULL, CLSCTX_ALL, __uuidof(IPolicyConfigVista), (LPVOID*)&pPolicyConfig); if (SUCCEEDED(hr)) { hr = pPolicyConfig->SetDefaultEndpoint(devID, reserved); pPolicyConfig->Release(); } return hr; } BOOL ResourceWatcherFSM::SetDefaultAudioDevice() { CSmartPointer spFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; CSimpleStringA strAudioName; BOOL bRet = FALSE; ErrorCodeEnum ec = spFunction->OpenConfig(Config_Root, spConfig); if (ec != 0) { Dbg("open root config failed!"); return FALSE; } ec = spConfig->ReadConfigValue("Audio", "handfree_out_dev", strAudioName); if (strAudioName.IsNullOrEmpty()) { Dbg("handfree_out_dev is nullptr or empty!!"); return FALSE; } Dbg("The hand_free_dev: %s", (LPCTSTR)strAudioName); CSimpleStringW strwAudioName = CSimpleStringA2W(strAudioName); HRESULT hr = CoInitialize(NULL); if (SUCCEEDED(hr)) { IMMDeviceEnumerator* pEnum = NULL; // Create a multimedia device enumerator. hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnum); if (SUCCEEDED(hr)) { //判断是否是默认的音频设备,是就退出 bool bExit = false; IMMDevice* pDefDevice = NULL; hr = pEnum->GetDefaultAudioEndpoint(eRender, eMultimedia, &pDefDevice); if (SUCCEEDED(hr)) { IPropertyStore* pStore; hr = pDefDevice->OpenPropertyStore(STGM_READ, &pStore); if (SUCCEEDED(hr)) { PROPVARIANT friendlyName; PropVariantInit(&friendlyName); hr = pStore->GetValue(PKEY_Device_FriendlyName, &friendlyName); if (SUCCEEDED(hr)) { CSimpleStringW strTmp = friendlyName.pwszVal; Dbg("default: %ws", (LPCWSTR)strTmp); if (strTmp.IsStartWith(strwAudioName)) { bExit = true; } PropVariantClear(&friendlyName); } pStore->Release(); } pDefDevice->Release(); } if (bExit) { pEnum->Release(); return TRUE; } IMMDeviceCollection* pDevices; // Enumerate the output devices. hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices); if (SUCCEEDED(hr)) { UINT count; pDevices->GetCount(&count); if (SUCCEEDED(hr)) { for (int i = 0; i < count; i++) { bool bFind = false; IMMDevice* pDevice; hr = pDevices->Item(i, &pDevice); if (SUCCEEDED(hr)) { LPWSTR wstrID = NULL; hr = pDevice->GetId(&wstrID); if (SUCCEEDED(hr)) { IPropertyStore* pStore; hr = pDevice->OpenPropertyStore(STGM_READ, &pStore); if (SUCCEEDED(hr)) { PROPVARIANT friendlyName; PropVariantInit(&friendlyName); hr = pStore->GetValue(PKEY_Device_FriendlyName, &friendlyName); if (SUCCEEDED(hr)) { // if no options, print the device // otherwise, find the selected device and set it to be default CSimpleStringW strTmp = friendlyName.pwszVal; Dbg("%d: %ws", i, (LPCWSTR)strTmp); if (strTmp.IsStartWith(strwAudioName)) { bFind = true; HRESULT hr = SetDefaultAudioPlaybackDevice(wstrID); if (SUCCEEDED(hr)) { Dbg("set default audio player succ."); bRet = TRUE; } else { Dbg("set default audio player failed"); } } PropVariantClear(&friendlyName); } pStore->Release(); } } pDevice->Release(); } if (bFind) { break; } } } pDevices->Release(); } pEnum->Release(); } } CoUninitialize(); return bRet; } #endif //RVC_OS_WIN BOOL ResourceWatcherFSM::DetectIsFirstRunAtBoot() { CSystemRunInfo runInfo = { 0 }; GetEntityBase()->GetFunction()->GetSystemRunInfo(runInfo); BOOL bSet = FALSE; CBootInfo bootInfo = { 0 }; CSmallDateTime dateTime; Dbg("systemRunInfo time: %s", (LPCTSTR)runInfo.tmStart.ToTimeString()); ErrorCodeEnum erroCode = GetEntityBase()->GetFunction()->GetRebootInfo(/*runInfo.tmStart*/dateTime, bootInfo); Dbg("bootInfor time: %s", (LPCTSTR)bootInfo.tmStart.ToTimeString()); CSmallDateTime systemBootTime; BOOL bRet = GetSystemBootTime(systemBootTime); if (bRet && systemBootTime > bootInfo.tmStart) { ErrorCodeEnum eRet = GetEntityBase()->GetFunction()->SetSysVar(SYSVAR_FRAMEWORK_FIRST_BOOT, SYSVAR_FRAMEWORK_FIRST_BOOT_YES); if (eRet != Error_Succeed) { Dbg("Set %s with %s failed: %d", SYSVAR_FRAMEWORK_FIRST_BOOT, SYSVAR_FRAMEWORK_FIRST_BOOT_YES, eRet); } bSet = TRUE; std::map srcData; srcData.insert(std::make_pair("OSStartTime", systemBootTime.ToTimeString().GetData())); srcData.insert(std::make_pair("AppStartTime", (LPCTSTR)runInfo.tmStart.ToTimeString())); srcData.insert(std::make_pair("AppLastStartTime", (LPCTSTR)bootInfo.tmStart.ToTimeString())); auto ret = generateJsonStr(srcData); LogWarn(Severity_Middle, Error_Debug, LOG_RESOURCEWATCHER_FIRST_RUN_AFTER_BOOT, ret.second.c_str()); } else { GetEntityBase()->GetFunction()->SetSysVar(SYSVAR_FRAMEWORK_FIRST_BOOT, SYSVAR_FRAMEWORK_FIRST_BOOT_NO); bSet = FALSE; } return bSet; } UINT ResourceWatcherFSM::GetSystemDisplayVersion(CSimpleStringA & strVersion) { UINT result = 0; const char filePath[] = "/etc/os-version"; strVersion.Clear(); char tmp[33]; memset(tmp, 0, 33); inifile_read_str_s("Version", "MajorVersion", "unknown", tmp, 32, filePath); strVersion = tmp; strVersion += "."; memset(tmp, 0, 33); inifile_read_str_s("Version", "MinorVersion", "unknown", tmp, 32, filePath); strVersion += tmp; strVersion += "."; result = atoi(tmp); memset(tmp, 0, 33); inifile_read_str_s("Version", "OsBuild", "unknown", tmp, 32, filePath); strVersion += tmp; return result; } void ResourceWatcherFSM::UploadSysVersionInfo(UINT & ver) { std::map srcData; CSimpleStringA osver; ver = GetSystemDisplayVersion(osver); srcData.insert(std::make_pair("os-version", osver)); ////当前操作系统版本(系统信息) tk_utsname_t t; osutil_uname(&t); srcData.insert(std::make_pair("sysname", t.sysname)); ////当前操作系统名 srcData.insert(std::make_pair("release", t.release)); ////当前发布级别 srcData.insert(std::make_pair("version", t.version)); ////当前发布版本 srcData.insert(std::make_pair("machine", t.machine)); ////当前硬件体系类型 do { std::string sucContent, failedContent; std::string cmd("cat /proc/cpuinfo |grep \"model name\" | awk 'NR==1{print $4}'"); bool ret = SP::Module::Util::ShelllExecute(cmd, sucContent, failedContent); Dbg("{%s}:{%s}{%s}", cmd.c_str(), sucContent.c_str(), failedContent.c_str()); std::size_t found = sucContent.rfind("\n"); if (found != std::string::npos) { sucContent.replace(found, strlen("\n"), ""); } srcData.insert(std::make_pair("cpu-type", sucContent)); } while (false); //#if defined(RVC_OS_LINUX) // CSystemStaticInfo sysInfo; // ErrorCodeEnum eErr = GetEntityBase()->GetFunction()->GetSystemStaticInfo(sysInfo); // if (eErr == Error_Succeed) { // termInfo["MachineMode"] = (LPCTSTR)sysInfo.strMachineModel; // termInfo["MachineSN"] = (LPCTSTR)sysInfo.strMachineSN; // } //#endif //RVC_OS_LINUX auto ret = generateJsonStr(srcData); LogWarn(Severity_Middle, Error_Hardware, LOG_RESOURCEWATCHER_SYSTEMINFO, ret.second.c_str()); } string ResourceWatcherFSM::CPUProcessStatus() { CSmartPointer spFunction = this->GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum erroCode = Error_Unexpect; spFunction->OpenConfig(Config_Software, spConfig); int cpuTop = 0; erroCode = spConfig->ReadConfigValueInt("TOPProcess", "cpu", cpuTop); if (cpuTop == 0) { return ""; } map nameProcess; CSystemRunInfo runInfo = { 0 }; GetEntityBase()->GetFunction()->GetSystemRunInfo(runInfo); for (int i = 0; i < runInfo.strRunningEntityNames.GetCount(); i++) { string entityName = runInfo.strRunningEntityNames[i].GetData(); CEntityRunInfo entityInfo = { 0 }; GetEntityBase()->GetFunction()->GetEntityRunInfo(entityName.c_str(), entityInfo); //Dbg("No. %d Current run entity : %s, procesID = %d !", i + 1, entityName, entityInfo.dwProcessID); nameProcess[to_string(entityInfo.dwProcessID)] = entityName; } //cout << "---------CPU----------" << endl; int cpu_num = sysconf(_SC_NPROCESSORS_CONF); //cout << "cpu number = " << cpu_num << endl; FILE* fp; char buffer[2048]; string cmd = "ps c -eo pid,%cpu,command | sort -k2 -rn | head -" + to_string(cpuTop); fp = popen(cmd.c_str(), "r"); int i = 0; string s; string str[3]; //cpu Dbg("CPU TOP %d PROCESS!", cpuTop); string topMessage = ""; while (i < cpuTop) { fgets(buffer, sizeof(buffer), fp); s = buffer; istringstream is(s); is >> str[0] >> str[1] >> str[2]; double temp; stringstream ss1; ss1 << str[1]; ss1 >> temp; temp = temp / cpu_num; //stringstream tss; /*stringstream ss2; ss2 << temp; ss2 >> str[1];*/ stringstream ss2; ss2 << std::setiosflags(std::ios::fixed) << std::setprecision(2) << temp; str[1] = ss2.str(); //printf("%s", s.c_str()); if (nameProcess.find(str[0]) != nameProcess.end()) { str[2] = nameProcess[str[0]]; } //cout << str[0] << ", " << str[1] << "%, " << str[2] << endl; //cout << s; //Dbg("Process id = %s, CPU usage = %s, Process Name = %s. ", str[0].c_str(), (str[1] + "%").c_str() , str[2].c_str()); topMessage = topMessage + "\"" + str[2] + "\"" + ":\"" + str[1] + "%\""; if (i != cpuTop - 1) { topMessage += ","; } ++i; } topMessage += "}"; //Dbg("%s", topMessage.c_str()); /*LogWarn(Severity_Low, Error_Resource, LOG_EVT_RESOURCE_MEMORY_TOO_HIGH, CSimpleStringA::Format("%s", topMessage.c_str()) );*/ pclose(fp); return topMessage; } string ResourceWatcherFSM::MemoryProcessStatus() { CSmartPointer spFunction = this->GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum erroCode = Error_Unexpect; spFunction->OpenConfig(Config_Software, spConfig); int memTop = 0; erroCode = spConfig->ReadConfigValueInt("TOPProcess", "mem", memTop); if (memTop == 0) { return ""; } map nameProcess; CSystemRunInfo runInfo = { 0 }; GetEntityBase()->GetFunction()->GetSystemRunInfo(runInfo); for (int i = 0; i < runInfo.strRunningEntityNames.GetCount(); i++) { string entityName = runInfo.strRunningEntityNames[i].GetData(); CEntityRunInfo entityInfo = { 0 }; GetEntityBase()->GetFunction()->GetEntityRunInfo(entityName.c_str(), entityInfo); //Dbg("No. %d Current run entity : %s, procesID = %d !", i + 1, entityName, entityInfo.dwProcessID); nameProcess[to_string(entityInfo.dwProcessID)] = entityName; } FILE* fp; char buffer[2048]; string cmd = "ps c -eo pid,%mem,rss,command | sort -k3 -rn | head -" + to_string(memTop); fp = popen(cmd.c_str(), "r"); int i = 0; string s; string str[4]; //cout << "---------MEMORY----------" << endl; //mem Dbg("MEM TOP %d PROCESS!", memTop); string topMessage = ""; while (i < memTop) { fgets(buffer, sizeof(buffer), fp); s = buffer; istringstream is(s); is >> str[0] >> str[1] >> str[2] >> str[3]; double temp; stringstream ss1; ss1 << str[2]; ss1 >> temp; temp = temp / (1024 * 1024); /* stringstream ss2; ss2 << temp; ss2 >> str[2];*/ //printf("%s", s.c_str()); stringstream ss2; ss2 << std::setiosflags(std::ios::fixed) << std::setprecision(2) << temp; str[2] = ss2.str(); if (nameProcess.find(str[0]) != nameProcess.end()) { str[3] = nameProcess[str[0]]; } //cout << str[0] << ", " << str[1] << ", " << str[2] << " GB," << str[3] << endl; //Dbg("Process id = %s, Memory usage = %s, Memory size = %s, Process Name = %s. ", //str[0].c_str(), (str[1] + "%").c_str(), (str[2] + " GB").c_str(), str[3].c_str()); //topMessage = topMessage + "\"" + str[3] + "\"" + ":" + "\"" + str[1] + "%|" + str[2] + " GByte\""; topMessage = topMessage + "\"" + str[3] + "\"" + ":" + "\"" + str[1] + "%\""; if (i != memTop - 1) { topMessage += ","; } //cout << s; ++i; } topMessage += "}"; //Dbg("%s", topMessage.c_str()); /* LogWarn(Severity_Low, Error_Resource, LOG_EVT_RESOURCE_CPU_TOO_HIGH, CSimpleStringA::Format("%s", topMessage.c_str()) );*/ pclose(fp); return topMessage; } void ResourceWatcherFSM::HardwareInfoTimer(void* pData) { GetSystemCPUStatus(); GetSystemMemoryStatus(); GetSystemDiskStatus(); GetOperationDiskStatus(); GetMainLinkStatus(); GetEntityBase()->GetFunction()->ResetTimer(TIMER_HARDWARE_CHECK, MAX_HARDWARE_CHECK_TIME * 2); } void ResourceWatcherFSM::LinkDetect(int detectType, const char* url, bool &status, uint &delay) { timeval begin, end; uint tInterval = 0; bool flag = false; string tUrl = url; string host = "http://"; if (tUrl.find("http") == string::npos) { tUrl = host + tUrl; } char tmpUrl[1024] = { 0 }; strcpy(tmpUrl, tUrl.c_str()); Dbg("Check url:[%s].", url); gettimeofday(&begin, NULL); //bool flag = http_probe(tmpUrl, 5000, 0); string msg; int curFlag = HttpProbe(tmpUrl, msg, 5); gettimeofday(&end, NULL); tInterval = (end.tv_sec - begin.tv_sec) * 1000 + (end.tv_usec - begin.tv_usec) / 1000; if (curFlag > 0 && curFlag < 400) { Dbg("HTTP SUCCESS!, http code = %d, error msg = %s.", curFlag, msg.c_str()); status = true; } else { Dbg("HTTP FAILED!, http code = %d, error msg = %s.", curFlag, msg.c_str()); status = false; } delay = tInterval; } ErrorCodeEnum ResourceWatcherFSM::BizLinkDetect( SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum ec = Error_Succeed; int detectType = ctx->Req.protocol; CSimpleStringA url = ctx->Req.bizLink; bool linkStatus = false; uint delay = 0; LinkDetect(detectType, url.GetData(), linkStatus, delay); ctx->Ans.bizLinkStatus = linkStatus; ctx->Ans.bizLinkDelayMS = delay; ctx->Ans.intParam = 0; if (ctx != NULL) { ctx->Answer(ec); } return ec; } ErrorCodeEnum ResourceWatcherFSM::CheckNetType( SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum ec = Error_Succeed; int netType = 0; //默认未知 CSimpleStringA tmpVendor(""), tmpDevSN(""), tmpDLLVersion(""); GetEntityBase()->GetFunction()->GetSysVar("FWBVendor", tmpVendor); GetEntityBase()->GetFunction()->GetSysVar("FWBDevSN", tmpDevSN); GetEntityBase()->GetFunction()->GetSysVar("FWBVersion", tmpDLLVersion); if (tmpDLLVersion.GetLength() < 2) tmpDLLVersion = "8.1"; if (tmpDevSN.GetLength() > 12 && tmpDevSN.IndexOf("FWB") > 2) { Dbg("This is fwb device."); } else { int i = 0; int sockfd; struct ifconf ifconf; struct ifreq* ifreq; char buf[1024]; //初始化ifconf ifconf.ifc_len = 1024; ifconf.ifc_buf = buf; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket error"); exit(1); } //获取所有接口信息 ioctl(sockfd, SIOCGIFCONF, &ifconf); //逐个获取Ip地址 int size = ifconf.ifc_len / sizeof(struct ifreq); ifreq = (struct ifreq*)buf; string netName(ifreq->ifr_name); if(size == 1 && netName == "lo") //只有逻辑地址 -- 网线被拔出 { netType = 1; } else { for (i = size; i > 0; i--) { string netName(ifreq->ifr_name); //有其他网卡 -- 有线 if (netName != "lo") { netType = 2; } ifreq++; } } ctx->Ans.netType = netType; } if (ctx != NULL) { ctx->Answer(ec); } return ec; } ErrorCodeEnum ResourceWatcherFSM::GetBizLinks( SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum ec = Error_Succeed; int filter = ctx->Req.filter; //后续过滤使用 CAutoArray bizLinks; CAutoArray bizNames; int bizNum = 4; bizNames.Init(bizNum); bizLinks.Init(bizNum); int pos = 0; CSmartPointer spCtSettingConfig; GetEntityBase()->GetFunction()->OpenConfig(Config_CenterSetting, spCtSettingConfig); CSimpleStringA mLink(""),adLink(""), mgrUrl(""), mgrUrlNoBar(""); spCtSettingConfig->ReadConfigValue("Chromium", "UserMgrUrlFulture", mLink); if (mLink.GetLength() != 0) { bizNames[pos] = "主站点"; bizLinks[pos] = mLink; pos++; } spCtSettingConfig->ReadConfigValue("Chromium", "UserMgrAd", adLink); if (adLink.GetLength() != 0) { bizNames[pos] = "广告站点"; bizLinks[pos] = adLink; pos++; } spCtSettingConfig->ReadConfigValue("Chromium", "UserMgrUrl", mgrUrl); if (mgrUrl.GetLength() != 0) { bizNames[pos] = "业务站点1"; bizLinks[pos] = mgrUrl; pos++; } spCtSettingConfig->ReadConfigValue("Chromium", "UserMgrUrlNoSidebar", mgrUrlNoBar); if (mgrUrlNoBar.GetLength() != 0) { bizNames[pos] = "业务站点2"; bizLinks[pos] = mgrUrlNoBar; pos++; } ctx->Ans.bizLinks = bizLinks; ctx->Ans.bizNames = bizNames; if (ctx != NULL) { ctx->Answer(ec); } return ec; } void ResourceWatcherFSM::GetMainLinkStatus() { ErrorCodeEnum errorCode = Error_Succeed; CSmartPointer spCtSettingConfig; GetEntityBase()->GetFunction()->OpenConfig(Config_CenterSetting, spCtSettingConfig); ErrorCodeEnum erroCode = Error_Unexpect; CSimpleStringA mLink(""); erroCode = spCtSettingConfig->ReadConfigValue("Chromium", "UserMgrUrlFulture", mLink); MainLinkDetect mainDetect; //const char* mainLink = "www.google.com"; const char* mainLink = mLink.GetData(); bool curStatus = false; uint delay = 0; LinkDetect(0, mainLink, curStatus, delay); if (!curStatus) { Dbg("Main Link disconnected [%s].", mainLink); mainDetect.mainLinkStatus = curStatus; mainDetect.reversed1 = 0; mainDetect.reversed2 = ""; SpSendBroadcast(GetEntityBase()->GetFunction(), SP_MSG_OF(MainLinkDetect), SP_MSG_SIG_OF(MainLinkDetect), mainDetect); } else { Dbg("Main Link is connected [%s].", mainLink); } } BOOL ResourceWatcherFSM::ReadCPUInfo(CPUInfo * cpu) { FILE* fp; char buff[256]; CPUInfo* cpuInfo; cpuInfo = cpu; fp = fopen("/proc/stat", "r"); if (!fp) { Dbg("Read CPU Info FAILED!"); return FALSE; } fgets(buff, sizeof(buff), fp); sscanf(buff, "%s %u %u %u %u %u %u %u", cpuInfo->name, &cpuInfo->user, &cpuInfo->nice, &cpuInfo->system, &cpuInfo->idle, &cpuInfo->lowait, &cpuInfo->irq, &cpuInfo->softirq); fclose(fp); return TRUE; } void ResourceWatcherFSM::GetSystemCPUStatus() { CPUInfo* cpuOld = new CPUInfo(); CPUInfo* cpuNew = new CPUInfo(); BOOL oldFlag = ReadCPUInfo(cpuOld); sleep(1); BOOL newFlag = ReadCPUInfo(cpuNew); if (!(oldFlag && newFlag)) return; unsigned long oldInfo, newInfo; double cUsedRate = 0; //第一次(用户+优先级+系统+空闲)的时间 oldInfo = (unsigned long)(cpuOld->user + cpuOld->nice + cpuOld->system + cpuOld->idle + cpuOld->lowait + cpuOld->irq + cpuOld->softirq); //第二次(用户+优先级+系统+空闲)的时间 newInfo = (unsigned long)(cpuNew->user + cpuNew->nice + cpuNew->system + cpuNew->idle + cpuNew->lowait + cpuNew->irq + cpuNew->softirq); double totalTime = newInfo - oldInfo; double freeTime = cpuNew->idle - cpuOld->idle; cUsedRate = (totalTime - freeTime) / totalTime; if (cUsedRate < 0.8) { //Dbg("[CPU] used rate: %.1lf%%.", cUsedRate * 100); } else { /*LogWarn(Severity_Low, Error_Resource, LOG_EVT_RESOURCE_CPU_TOO_HIGH, CSimpleStringA::Format("CPU TOO HIGH! [CPU] used rate: %.1lf%%.", cUsedRate * 100) );*/ stringstream tss; tss << std::setiosflags(std::ios::fixed) << std::setprecision(2) << cUsedRate * 100; string warn = "{ \"total_used\":\"" + tss.str() + "%\"," + CPUProcessStatus(); Dbg("%s", warn.c_str()); LogWarn(Severity_Low, Error_Resource, LOG_EVT_RESOURCE_CPU_TOO_HIGH, CSimpleStringA::Format("%s", warn.c_str())); } } void ResourceWatcherFSM::GetSystemMemoryStatus() { MemInfo* memInfo = new MemInfo(); FILE* fd; char buff[256]; fd = fopen("/proc/meminfo", "r"); if (!fd) { Dbg("Read Memory INFO FAILED!"); return; } fgets(buff, sizeof(buff), fd); sscanf(buff, "%s %lu ", memInfo->infoName1, &memInfo->memTotal); fgets(buff, sizeof(buff), fd); sscanf(buff, "%s %lu ", memInfo->infoName2, &memInfo->memFree); fgets(buff, sizeof(buff), fd); sscanf(buff, "%s %lu ", memInfo->infoName3, &memInfo->memAvail); fclose(fd); double mUsedRate = 0; mUsedRate = (double)(memInfo->memTotal - memInfo->memAvail) / (double)memInfo->memTotal; char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; char szResult2[DEFAULT_OUTPUT_FORMAT_SIZE]; char szResult3[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(szResult, (double)(memInfo->memTotal) * 1024, 'G'); // 内存信息在 /proc/meminfo 中的单位为 KB ByteSprintf(szResult2, (double)(memInfo->memFree) * 1024, 'G'); ByteSprintf(szResult3, (double)(memInfo->memAvail) * 1024, 'G'); if (mUsedRate < 0.8) { //Dbg("[Memory] total: %s, free: %s, available: %s, [Memory] used rate: %.1lf%%.", szResult, szResult2, szResult3, mUsedRate * 100); } else { /*LogWarn(Severity_Low, Error_Resource, LOG_EVT_RESOURCE_MEMORY_TOO_HIGH, CSimpleStringA::Format("MEMORY TOO HIGH! -- [Memory] total: %s, free: %s, available: %s, [Memory] used rate: %.1lf%%.", szResult, szResult2, szResult3, mUsedRate * 100) );*/ char usedResult[DEFAULT_OUTPUT_FORMAT_SIZE]; ByteSprintf(usedResult, (double)(memInfo->memTotal) * 1024 * mUsedRate, 'G'); stringstream ss1; ss1 << std::setiosflags(std::ios::fixed) << std::setprecision(2) << mUsedRate * 100; string warn = "{ \"total\":\"" + string(szResult) + "\"," + "\"used\":\"" + ss1.str() + "%\"," + MemoryProcessStatus(); Dbg("%s", warn.c_str()); LogWarn(Severity_Low, Error_Resource, LOG_EVT_RESOURCE_MEMORY_TOO_HIGH, CSimpleStringA::Format("%s", warn.c_str())); } } void ResourceWatcherFSM::GetDiskStatusFrom(LPCTSTR path) { unsigned long long uiTotalBytes; unsigned long long uiFreeDiskBytes; char szResult[DEFAULT_OUTPUT_FORMAT_SIZE]; char szResult2[DEFAULT_OUTPUT_FORMAT_SIZE]; BOOL readFlag = DiskInfo::GetDiskSpace(path, uiTotalBytes, uiFreeDiskBytes); double dUsedRate = 1 - (uiFreeDiskBytes * kConversion[3]) / (uiTotalBytes * kConversion[3]); ByteSprintf(szResult, (double)uiTotalBytes); ByteSprintf(szResult2, (double)uiFreeDiskBytes); if (readFlag && (dUsedRate < 0.9)) { //Dbg("[Disk# %s] total: %s, free: %s, [Disk] used rate: %.1lf%%.", path, szResult, szResult2, dUsedRate * 100); } else { LogWarn(Severity_Low, Error_Resource, LOG_EVT_RESOURCE_HARDDISK_TOO_HIGH, CSimpleStringA::Format("DISK TOO HIGH! -- [Disk# %s] total: %s, free: %s, [Disk] used rate: %.1lf%%.", path, szResult, szResult2, dUsedRate * 100) ); } } void ResourceWatcherFSM::GetSystemDiskStatus() { GetDiskStatusFrom("/"); } void ResourceWatcherFSM::GetOperationDiskStatus() { GetDiskStatusFrom(m_uploadedVideoDirPath); } void ResourceWatcherFSM::switchWindowsEffect(const char* cfgFilePath, bool enable) { char tmp[33]; memset(tmp, 0, 33); inifile_read_str_s("Compositing", "Enabled", "", tmp, 32, cfgFilePath); if (strlen(tmp) == 0 || stricmp(tmp, "false") == 0) { if (enable) { inifile_write_str(cfgFilePath, "Compositing", "Enabled", "true"); LogWarn(Severity_Low, Error_InvalidState, LOG_RESOURCEWATCHER_COMPOSITING_CHANGE_ON, "to active window effect"); } } else if (stricmp(tmp, "true") == 0) { if (!enable) { inifile_write_str(cfgFilePath, "Compositing", "Enabled", "false"); LogWarn(Severity_Low, Error_InvalidState, LOG_RESOURCEWATCHER_COMPOSITING_CHANGE_OFF, "to inactive window effect"); } } } BOOL ResourceWatcherFSM::readDNSConfigFile(CSimpleStringA & result) { std::string succStr, errStr; if (SP::Module::Util::ShelllExecute("cat /etc/resolv.conf", succStr, errStr)) { result = succStr.c_str(); return TRUE; } else { return FALSE; } } void ResourceWatcherFSM::RecoverDDEClipboardEnable() { const std::string clipboardPath = "/usr/bin/dde-clipboard"; const std::string clipboardPathBak = "/usr/bin/dde-clipboard.bak"; if (!ExistsFileA(clipboardPath.c_str()) && ExistsFileA(clipboardPathBak.c_str())) { fileutil_copy_file(clipboardPath.c_str(), clipboardPathBak.c_str()); //fileutil_delete_file(clipboardPathBak.c_str()); LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHER_CLIPBOARD_RECOVER_ENABLE, "recover clipboard succ."); } else { Dbg("%s exists.", clipboardPath.c_str()); } } void ResourceWatcherFSM::ConfirmDDEClipboardDisable() { const std::string clipboardPath = "/usr/bin/dde-clipboard"; const std::string clipboardPathBak = "/usr/bin/dde-clipboard.bak"; char* clipboards[] = { "dde-clipboard", "dde-clipboardloader" }; if (!ExistsFileA(clipboardPath.c_str())) { Dbg("There are no any %s files.", clipboardPath.c_str()); if (ExistsFileA(clipboardPathBak.c_str())) { Dbg("%s exists.", clipboardPathBak.c_str()); } return; } if (0 != fileutil_copy_file(clipboardPathBak.c_str(), clipboardPath.c_str())) { LogWarn(Severity_Low, Error_Unexpect, LOG_RESOURCEWATCHER_CLIPBOARD_REMOVE_FAILED, "remove clipboard failed"); } else { fileutil_delete_file(clipboardPath.c_str()); osutil_terminate_related_process(clipboards, array_size(clipboards)); LogWarn(Severity_Low, Error_Process, LOG_RESOURCEWATCHER_CLIPBOARD_REMOVE_SUCC, "remove clipboard succ."); } } void ResourceWatcherFSM::ConfirmNotificationCenterDisable() { const char* osd_file_path = "/usr/lib/deepin-daemon/dde-osd"; const char* osd_bak_file_path = "/usr/lib/deepin-daemon/dde-osd.bak"; CSmartPointer spConfig; GetEntityBase()->GetFunction()->OpenConfig(Config_Cache, spConfig); int flag = 0; spConfig->ReadConfigValueInt("UOSFeatures", "NotifyCenterSupport", flag); if (flag == 1) { Dbg("allow the dde-osd process alive."); if (!ExistsFileA(osd_file_path) && ExistsFileA(osd_bak_file_path)) { fileutil_copy_file(osd_file_path, osd_bak_file_path); LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHER_OSD_RECOVER_ENABLE, "recover dde osd succ."); } } else { if (ExistsFileA(osd_file_path) && !ExistsFileA(osd_bak_file_path)) { char* relates[] = { "dde-osd" }; if (0 != fileutil_copy_file(osd_bak_file_path, osd_file_path)) { LogWarn(Severity_Low, Error_Unexpect, LOG_RESOURCEWATCHER_CLIPBOARD_REMOVE_FAILED, "remove dde osd failed"); } else { osutil_terminate_related_process(relates, array_size(relates)); fileutil_delete_file(osd_file_path); LogWarn(Severity_Low, Error_Process, LOG_RESOURCEWATCHER_OSD_REMOVE_SUCC, "remove dde osd succ."); } } } } BOOL ResourceWatcherFSM::SetLocalDNSWithResolv(LPCTSTR dns1, LPCTSTR dns2) { const char* dnsPath = "/etc/resolv.conf"; const int res = access(dnsPath, W_OK); if (res == 0) { CSimpleStringA timeStamp = CSmallDateTime::GetNow().ToTimeString(); FILE* resolv = fopen(dnsPath, "w+"); int state = fprintf(resolv, "#Update by VTM %s\nnameserver %s\nnameserver %s\n", timeStamp.GetData(), dns1, dns2); fclose(resolv); if (state < 0) { LogWarn(Severity_Low, Error_Unexpect, LOG_RESOURCEWATCHER_DNS_CHANGE_FAILED, CSimpleStringA::Format("update dns config for %s|%s failed: err: %d", dns1, dns2, errno)); return FALSE; } else { LogWarn(Severity_Low, Error_Unexpect, LOG_RESOURCEWATCHER_DNS_CHANGE_SUCC, CSimpleStringA::Format("update dns with resolv for %s|%s succ!", dns1, dns2)); return TRUE; } } LogWarn(Severity_Low, Error_Unexpect, LOG_RESOURCEWATCHER_DNS_CHANGE_FAILED, CSimpleStringA::Format("access dns with resolv failed err: %d, rc:%d", errno, res)); return FALSE; } /** 在厂商机器查看了信息,不能以这里面的内容为准 [Gifur@2021910]*/ BOOL ResourceWatcherFSM::SetLocalDNSWithNetworkManager(LPCTSTR dns1, LPCTSTR dns2) { BOOL result = FALSE; const char* connectDirPath = "/etc/NetworkManager/system-connections"; array_header_t* arr; arr = fileutil_get_sub_files_a(connectDirPath); if (arr) { do { for (int i = 0; i < arr->nelts; ++i) { char* dir = ARRAY_IDX(arr, i, char*); LogWarn(Severity_Low, Error_Unexpect, LOG_RESOURCEWATCHER_DNS_INFO_UPLOAD, CSimpleStringA::Format("%d: %s", i + 1, dir)); } if (arr->nelts == 0) { LogWarn(Severity_Low, Error_Duplication, LOG_RESOURCEWATCHER_DNS_INFO_UPLOAD, CSimpleStringA::Format("%s: no any sub files", connectDirPath)); } toolkit_array_free2(arr); return result; } while (false); if (arr->nelts != 1) { LogWarn(Severity_Low, Error_Duplication, LOG_RESOURCEWATCHER_SYSCONNECT_DUPLICATE, CSimpleStringA::Format("%s: unexpect connects count: %d", connectDirPath, arr->nelts)); } else { char szDestPath[256] = { 0 }; char* dir = ARRAY_IDX(arr, 0, char*); strcpy(szDestPath, dir); do { char value[128]; inifile_read_str_s("connection", "interface-name", "", value, 127, szDestPath); if (strlen(value) == 0) { LogWarn(Severity_Low, Error_Duplication, LOG_RESOURCEWATCHER_DNS_CONNECTION_INFO_UNEXPECT, CSimpleStringA::Format("get interface name from %s failed.", szDestPath)); break; } memset(value, 0, sizeof(value)); inifile_read_str_s("ipv4", "dns", "", value, 127, szDestPath); bool toUpdate = true; if (strlen(value) > 0) { CSimpleStringA DNSes(value); auto arr = DNSes.Split(';'); int cf1 = 0, cf2 = 0; for (int i = 0; i < arr.GetCount(); ++i) { if (arr[i].Compare(dns1) == 0) cf1++; if (arr[i].Compare(dns2) == 0) cf2++; } if (cf1 > 0 && cf2 > 0) { toUpdate = false; Dbg("already exists: %s, needless to update.", value); result = TRUE; } } if (toUpdate) { CSimpleStringA newLine(dns1); if (newLine.Compare(dns2) != 0) { newLine += ";"; newLine += dns2; newLine += ";"; } else { newLine += ";"; } inifile_write_str(szDestPath, "ipv4", "dns", newLine); inifile_write_str(szDestPath, "ipv4", "ignore-auto-dns", "true"); Dbg("to update services."); std::string nor, err; SP::Module::Util::ShelllExecute("service NetworkManager restart", nor, err); Dbg("restart service done!"); LogWarn(Severity_Low, Error_Unexpect, LOG_RESOURCEWATCHER_DNS_CHANGE_NM_SUCC, CSimpleStringA::Format("update dns with netwokrMange for %s|%s succ!", dns1, dns2)); result = TRUE; } } while (false); } toolkit_array_free2(arr); } else { LogWarn(Severity_Low, Error_Duplication, LOG_RESOURCEWATCHER_DNS_INFO_UPLOAD, CSimpleStringA::Format("%s: no such directory or not any sub files", connectDirPath)); //LogWarn(Severity_Low, Error_Duplication, LOG_RESOURCEWATCHER_SYSCONNECT_DUPLICATE, // CSimpleStringA::Format("%s: no such directory or not any sub files", connectDirPath)); } return result; } /* * 桌面版本自带的NetworkManage管理服务与Interface的设置有冲突,如果手工改动Interface的配置,则NetworkManage会失效 * UOS默认使用NetworkMange接管网卡的管理,所以为了适应UOS,此种方式暂不实现 */ BOOL ResourceWatcherFSM::SetLocalDNSWithInterfaces(LPCTSTR dns1, LPCTSTR dns2) { return FALSE; } void ResourceWatcherFSM::ConfirmDNSConfigHasSet() { LOG_FUNCTION(); CSimpleStringA dns1, dns2; #if 1 CSmartPointer spConfig; GetEntityBase()->GetFunction()->OpenConfig(Config_Software, spConfig); #ifdef UNDER_PRODUCT_ENV spConfig->ReadConfigValue("DNS", "dns1", dns1); spConfig->ReadConfigValue("DNS", "dns2", dns2); Dbg("prd enviromemt"); #else spConfig->ReadConfigValue("DNSTest", "dns1", dns1); spConfig->ReadConfigValue("DNSTest", "dns2", dns2); Dbg("test enviromemt"); #endif // DEBUG #else dns1 = m_strDefaultDns; dns2 = m_strBackupDns; if (!m_nEnableSetDns) { Dbg("no enable set dns server."); return; } #endif if (dns1.IsNullOrEmpty() && dns2.IsNullOrEmpty()) { Dbg("not any dns set at entity config."); return; } if (dns2.IsNullOrEmpty()) dns2 = dns1; if (dns1.IsNullOrEmpty()) dns1 = dns2; CSimpleStringA str; readDNSConfigFile(str); do { std::string a(str.GetData()); SP::Utility::replaceInPlace(a, "\n", "|"); LogWarn(Severity_Low, Error_Unexpect, LOG_RESOURCEWATCHER_DNS_INFO_UPLOAD, CSimpleStringA::Format("%s $$ %s|%s", a.c_str(), m_strDefaultDns.GetData(), m_strBackupDns.GetData())); //SetLocalDNSWithNetworkManager(dns1, dns2); } while (false); return; if (!str.IsNullOrEmpty()) { CAutoArray arr = str.Split('\n'); CSimpleStringA check1("nameserver "); CSimpleStringA check2("nameserver "); check1 += dns1; check2 += dns2; int cf1 = 0, cf2 = 0; for (int i = 0; i < arr.GetCount(); ++i) { if (arr[i].Compare(check1) == 0) cf1++; if (arr[i].Compare(check2) == 0) cf2++; } if (cf1 > 0 && cf2 > 0) { Dbg("dns has been config before:"); Dbg(str); return; } } Dbg("to set dns config..."); SetLocalDNSWithResolv(dns1, dns2); //SetLocalDNSWithNetworkManager(dns1, dns2); Dbg("set dns config done!"); } void ResourceWatcherFSM::ConfirmWindowEffectHasBeenOpen() { array_header_t* arr; arr = fileutil_get_sub_dirs_a("/home"); if (arr) { int i; for (i = 0; i < arr->nelts; ++i) { char szDestSubDir[256] = { 0 }; char* dir = ARRAY_IDX(arr, i, char*); Dbg("sub dir: %s", dir); strcpy(szDestSubDir, dir); strcat(szDestSubDir, SPLIT_SLASH_STR); strcat(szDestSubDir, ".config/kwinrc"); if (ExistsFileA(szDestSubDir)) { switchWindowsEffect(szDestSubDir, true); } } toolkit_array_free2(arr); } }